Private
Public Access
1
0

feat: Fluent UI Outlook Lite + connections mockup

This commit is contained in:
2026-04-14 18:52:25 +00:00
parent 1199eff6c3
commit dfa4010406
34820 changed files with 1003813 additions and 205 deletions

2075
node_modules/@fluentui/react-spinbutton/CHANGELOG.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

15
node_modules/@fluentui/react-spinbutton/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,15 @@
@fluentui/react-spinbutton
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Note: Usage of the fonts and icons referenced in Fluent UI React is subject to the terms listed at https://aka.ms/fluentui-assets-license

35
node_modules/@fluentui/react-spinbutton/README.md generated vendored Normal file
View File

@@ -0,0 +1,35 @@
# @fluentui/react-spinbutton
**SpinButton component for [Fluent UI React](https://react.fluentui.dev/)**
SpinButtons are used to allow numeric input bounded between minimum and maximum values with buttons to increment and decrement the input value. Values can also be manipulated via the keyboard.
### Usage
Import SpinButton:
```js
import { SpinButton } from '@fluentui/react-spinbutton';
```
#### Examples
```jsx
<SpinButton defaultValue={5}/>
<SpinButton value={value} onChange={onSpinButtonChange}/>
```
See [Fluent UI Storybook](https://react.fluentui.dev/) for more detailed usage examples.
Alternatively, run Storybook locally with:
1. `yarn start`
2. Select `react-spinbutton` from the list.
### Specification
See [Spec.md](./Spec.md).
### Migration Guide
When upgrading to Fluent UI v9 see the [upgrade guide](https://react.fluentui.dev/?path=/docs/concepts-migration-from-v8-components-spinbutton-migration--docs) for guidance on updating to the latest SpinButton implementation.

185
node_modules/@fluentui/react-spinbutton/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,185 @@
import type { ComponentProps } from '@fluentui/react-utilities';
import type { ComponentState } from '@fluentui/react-utilities';
import type { DistributiveOmit } from '@fluentui/react-utilities';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
import type { JSXElement } from '@fluentui/react-utilities';
import * as React_2 from 'react';
import type { Slot } from '@fluentui/react-utilities';
import { SlotClassNames } from '@fluentui/react-utilities';
/**
* Render the final JSX of SpinButton
*/
export declare const renderSpinButton_unstable: (state: SpinButtonBaseState) => JSXElement;
/**
* A SpinButton allows someone to incrementally adjust a value in small steps.
*/
export declare const SpinButton: ForwardRefComponent<SpinButtonProps>;
export declare type SpinButtonBaseProps = DistributiveOmit<SpinButtonProps, 'appearance' | 'size'>;
export declare type SpinButtonBaseState = DistributiveOmit<SpinButtonState, 'appearance' | 'size'>;
export declare type SpinButtonBounds = 'none' | 'min' | 'max' | 'both';
export declare type SpinButtonChangeEvent = React_2.MouseEvent<HTMLButtonElement> | React_2.ChangeEvent<HTMLElement> | React_2.FocusEvent<HTMLInputElement> | React_2.KeyboardEvent<HTMLInputElement>;
export declare const spinButtonClassNames: SlotClassNames<SpinButtonSlots>;
export declare type SpinButtonOnChangeData = {
value?: number | null;
displayValue?: string;
};
/**
* SpinButton Props
*/
export declare type SpinButtonProps = Omit<ComponentProps<Partial<SpinButtonSlots>, 'input'>, 'defaultValue' | 'onChange' | 'size' | 'value'> & {
/**
* Controls the colors and borders of the input.
* @default 'outline'
*/
appearance?: 'outline' | 'underline' | 'filled-darker' | 'filled-lighter';
/**
* Initial value of the control (assumed to be valid). Updates to this prop will not be respected.
*
* Use this if you intend for the SpinButton to be an uncontrolled component which maintains its
* own value. For a controlled component, use `value` instead. (Mutually exclusive with `value`.)
*
* Use `null` to indicate the control has no value.
*/
defaultValue?: number | null;
/**
* String representation of `value`.
*
* Use this when displaying the value to users as something other than a plain number.
* For example, when displaying currency values this might be "$1.00" when value is `1`.
*
* Only provide this if the SpinButton is a controlled component where you are maintaining its
* current state and passing updates based on change events. When SpinButton is used as an
* uncontrolled component this prop is ignored.
*/
displayValue?: string;
/**
* Max value of the control. If not provided, the control has no maximum value.
*/
max?: number;
/**
* Min value of the control. If not provided, the control has no minimum value.
*/
min?: number;
/**
* Callback for when the committed value changes.
* - User presses the up/down buttons (on single press or every spin)
* - User presses the up/down arrow keys (on single press or every spin)
* - User *commits* edits to the input text by focusing away (blurring) or pressing enter.
* Note that this is NOT called for every key press while the user is editing.
*/
onChange?: (event: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => void;
/**
* How many decimal places the value should be rounded to.
*
* The default is calculated based on the precision of `step`: i.e. if step = 1, precision = 0.
* step = 0.0089, precision = 4. step = 300, precision = 2. step = 23.00, precision = 2.
*/
precision?: number;
/**
* Size of the input.
* @default 'medium'
*/
size?: 'small' | 'medium';
/**
* Difference between two adjacent values of the control.
* This value is used to calculate the precision of the input if no `precision` is given.
* The precision calculated this way will always be greater than or equal 0.
* @default 1
*/
step?: number;
/**
* Large difference between two values. This should be greater than `step` and is used
* when users hit the Page Up or Page Down keys.
* @default 1
*/
stepPage?: number;
/**
* Current value of the control (assumed to be valid).
*
* Only provide this if the SpinButton is a controlled component where you are maintaining its
* current state and passing updates based on change events; otherwise, use the `defaultValue`
* property.
*
* Use `null` to indicate the control has no value.
*
* Mutually exclusive with `defaultValue`.
*/
value?: number | null;
};
export declare type SpinButtonSlots = {
/**
* The root element of SpinButton is a container `<div>`.
* The root slot receives the `className` and `style` specified on the `<SpinButton>`.
* All other native props are applied to the primary slot: `input`.
*/
root: NonNullable<Slot<'span'>>;
/**
* Input that displays the current value and accepts direct input from the user.
* Displayed value is formatted.
*
* This is the primary slot.
*/
input: NonNullable<Slot<'input'>>;
/**
* Renders the increment control.
*/
incrementButton: NonNullable<Slot<'button'>>;
/**
* Renders the decrement control.
*/
decrementButton: NonNullable<Slot<'button'>>;
};
export declare type SpinButtonSpinState = 'rest' | 'up' | 'down';
/**
* State used in rendering SpinButton
*/
export declare type SpinButtonState = ComponentState<SpinButtonSlots> & Required<Pick<SpinButtonProps, 'appearance' | 'size'>> & {
/**
* State used to track which direction, if any, SpinButton is currently spinning.
* @default 'rest'
*/
spinState: SpinButtonSpinState;
/**
* State used to track if the value is at the range bounds of [min-max].
* @default 'none'
*/
atBound: SpinButtonBounds;
};
/**
* Create the state required to render SpinButton.
*
* The returned state can be modified with hooks such as useSpinButtonStyles_unstable,
* before being passed to renderSpinButton_unstable.
*
* @param props - props from this instance of SpinButton
* @param ref - reference to root HTMLElement of SpinButton
*/
export declare const useSpinButton_unstable: (props: SpinButtonProps, ref: React_2.Ref<HTMLInputElement>) => SpinButtonState;
/**
* Create the base state required to render SpinButton without design-specific props.
*
* @param props - props from this instance of SpinButton (without appearance/size)
* @param ref - reference to root HTMLElement of SpinButton
*/
export declare const useSpinButtonBase_unstable: (props: SpinButtonBaseProps, ref: React_2.Ref<HTMLInputElement>) => SpinButtonBaseState;
/**
* Apply styling to the SpinButton slots based on the state
*/
export declare const useSpinButtonStyles_unstable: (state: SpinButtonState) => SpinButtonState;
export { }

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
SpinButton: function() {
return _index.SpinButton;
},
renderSpinButton_unstable: function() {
return _index.renderSpinButton_unstable;
},
spinButtonClassNames: function() {
return _index.spinButtonClassNames;
},
useSpinButtonBase_unstable: function() {
return _index.useSpinButtonBase_unstable;
},
useSpinButtonStyles_unstable: function() {
return _index.useSpinButtonStyles_unstable;
},
useSpinButton_unstable: function() {
return _index.useSpinButton_unstable;
}
});
const _index = require("./components/SpinButton/index");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/SpinButton.ts"],"sourcesContent":["export type {\n SpinButtonBaseProps,\n SpinButtonBaseState,\n SpinButtonBounds,\n SpinButtonChangeEvent,\n SpinButtonOnChangeData,\n SpinButtonProps,\n SpinButtonSlots,\n SpinButtonSpinState,\n SpinButtonState,\n} from './components/SpinButton/index';\nexport {\n SpinButton,\n renderSpinButton_unstable,\n spinButtonClassNames,\n useSpinButtonStyles_unstable,\n useSpinButtonBase_unstable,\n useSpinButton_unstable,\n} from './components/SpinButton/index';\n"],"names":["SpinButton","renderSpinButton_unstable","spinButtonClassNames","useSpinButtonStyles_unstable","useSpinButtonBase_unstable","useSpinButton_unstable"],"mappings":";;;;;;;;;;;;eAYEA,iBAAU;;;eACVC,gCAAyB;;;eACzBC,2BAAoB;;;eAEpBE,iCAA0B;;;eAD1BD,mCAA4B;;;eAE5BE,6BAAsB;;;uBACjB,gCAAgC"}

View File

@@ -0,0 +1,24 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "SpinButton", {
enumerable: true,
get: function() {
return SpinButton;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _useSpinButton = require("./useSpinButton");
const _renderSpinButton = require("./renderSpinButton");
const _useSpinButtonStylesstyles = require("./useSpinButtonStyles.styles");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const SpinButton = /*#__PURE__*/ _react.forwardRef((props, ref)=>{
const state = (0, _useSpinButton.useSpinButton_unstable)(props, ref);
(0, _useSpinButtonStylesstyles.useSpinButtonStyles_unstable)(state);
(0, _reactsharedcontexts.useCustomStyleHook_unstable)('useSpinButtonStyles_unstable')(state);
return (0, _renderSpinButton.renderSpinButton_unstable)(state);
});
SpinButton.displayName = 'SpinButton';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SpinButton/SpinButton.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useSpinButton_unstable } from './useSpinButton';\nimport { renderSpinButton_unstable } from './renderSpinButton';\nimport { useSpinButtonStyles_unstable } from './useSpinButtonStyles.styles';\nimport type { SpinButtonProps } from './SpinButton.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * A SpinButton allows someone to incrementally adjust a value in small steps.\n */\nexport const SpinButton: ForwardRefComponent<SpinButtonProps> = React.forwardRef((props, ref) => {\n const state = useSpinButton_unstable(props, ref);\n\n useSpinButtonStyles_unstable(state);\n\n useCustomStyleHook_unstable('useSpinButtonStyles_unstable')(state);\n\n return renderSpinButton_unstable(state);\n});\n\nSpinButton.displayName = 'SpinButton';\n"],"names":["React","useSpinButton_unstable","renderSpinButton_unstable","useSpinButtonStyles_unstable","useCustomStyleHook_unstable","SpinButton","forwardRef","props","ref","state","displayName"],"mappings":"AAAA;;;;;;;;;;;;iEAEuB,QAAQ;+BACQ,kBAAkB;kCACf,qBAAqB;2CAClB,+BAA+B;qCAGhC,kCAAkC;AAKvE,MAAMK,aAAAA,WAAAA,GAAmDL,OAAMM,UAAU,CAAC,CAACC,OAAOC;IACvF,MAAMC,YAAQR,qCAAAA,EAAuBM,OAAOC;QAE5CL,uDAAAA,EAA6BM;QAE7BL,gDAAAA,EAA4B,gCAAgCK;IAE5D,WAAOP,2CAAAA,EAA0BO;AACnC,GAAG;AAEHJ,WAAWK,WAAW,GAAG"}

View File

@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
SpinButton: function() {
return _SpinButton.SpinButton;
},
renderSpinButton_unstable: function() {
return _renderSpinButton.renderSpinButton_unstable;
},
spinButtonClassNames: function() {
return _useSpinButtonStylesstyles.spinButtonClassNames;
},
useSpinButtonBase_unstable: function() {
return _useSpinButton.useSpinButtonBase_unstable;
},
useSpinButtonStyles_unstable: function() {
return _useSpinButtonStylesstyles.useSpinButtonStyles_unstable;
},
useSpinButton_unstable: function() {
return _useSpinButton.useSpinButton_unstable;
}
});
const _SpinButton = require("./SpinButton");
const _renderSpinButton = require("./renderSpinButton");
const _useSpinButton = require("./useSpinButton");
const _useSpinButtonStylesstyles = require("./useSpinButtonStyles.styles");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SpinButton/index.ts"],"sourcesContent":["export { SpinButton } from './SpinButton';\nexport type {\n SpinButtonBaseProps,\n SpinButtonBaseState,\n SpinButtonBounds,\n SpinButtonChangeEvent,\n SpinButtonOnChangeData,\n SpinButtonProps,\n SpinButtonSlots,\n SpinButtonSpinState,\n SpinButtonState,\n} from './SpinButton.types';\nexport { renderSpinButton_unstable } from './renderSpinButton';\nexport { useSpinButtonBase_unstable, useSpinButton_unstable } from './useSpinButton';\nexport { spinButtonClassNames, useSpinButtonStyles_unstable } from './useSpinButtonStyles.styles';\n"],"names":["SpinButton","renderSpinButton_unstable","useSpinButtonBase_unstable","useSpinButton_unstable","spinButtonClassNames","useSpinButtonStyles_unstable"],"mappings":";;;;;;;;;;;;eAASA,sBAAU;;;eAYVC,2CAAyB;;;eAEzBG,+CAAoB;;;eADpBF,yCAA0B;;;eACJG,uDAA4B;;;eADtBF,qCAAsB;;;4BAbhC,eAAe;kCAYA,qBAAqB;+BACI,kBAAkB;2CAClB,+BAA+B"}

View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "renderSpinButton_unstable", {
enumerable: true,
get: function() {
return renderSpinButton_unstable;
}
});
const _jsxruntime = require("@fluentui/react-jsx-runtime/jsx-runtime");
const _reactutilities = require("@fluentui/react-utilities");
const renderSpinButton_unstable = (state)=>{
(0, _reactutilities.assertSlots)(state);
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(state.root, {
children: [
/*#__PURE__*/ (0, _jsxruntime.jsx)(state.input, {}),
/*#__PURE__*/ (0, _jsxruntime.jsx)(state.incrementButton, {}),
/*#__PURE__*/ (0, _jsxruntime.jsx)(state.decrementButton, {})
]
});
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SpinButton/renderSpinButton.tsx"],"sourcesContent":["/** @jsxRuntime automatic */\n/** @jsxImportSource @fluentui/react-jsx-runtime */\n\nimport { assertSlots } from '@fluentui/react-utilities';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport type { SpinButtonBaseState, SpinButtonSlots } from './SpinButton.types';\n\n/**\n * Render the final JSX of SpinButton\n */\nexport const renderSpinButton_unstable = (state: SpinButtonBaseState): JSXElement => {\n assertSlots<SpinButtonSlots>(state);\n\n return (\n <state.root>\n <state.input />\n <state.incrementButton />\n <state.decrementButton />\n </state.root>\n );\n};\n"],"names":["assertSlots","renderSpinButton_unstable","state","root","input","incrementButton","decrementButton"],"mappings":";;;;+BAUaC;;;;;;4BATb,iCAAiD;gCAErB,4BAA4B;AAOjD,kCAAkC,CAACC;QACxCF,2BAAAA,EAA6BE;IAE7B,OAAA,WAAA,OACE,gBAAA,EAACA,MAAMC,IAAI,EAAA;;8BACT,eAAA,EAACD,MAAME,KAAK,EAAA,CAAA;8BACZ,eAAA,EAACF,MAAMG,eAAe,EAAA,CAAA;8BACtB,eAAA,EAACH,MAAMI,eAAe,EAAA,CAAA;;;AAG5B,EAAE"}

View File

@@ -0,0 +1,301 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
useSpinButtonBase_unstable: function() {
return useSpinButtonBase_unstable;
},
useSpinButton_unstable: function() {
return useSpinButton_unstable;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _reactfield = require("@fluentui/react-field");
const _reactutilities = require("@fluentui/react-utilities");
const _keyboardkeys = require("@fluentui/keyboard-keys");
const _index = require("../../utils/index");
const _reacticons = require("@fluentui/react-icons");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const DEFAULT_SPIN_DELAY_MS = 150;
const MIN_SPIN_DELAY_MS = 80;
const MAX_SPIN_TIME_MS = 1000;
// This is here to give an ease for the mouse held down case.
// Exact easing it to be defined. Once it is we'll likely
// pull this out into a util function in the SpinButton package.
const lerp = (start, end, percent)=>start + (end - start) * percent;
const useSpinButtonBase_unstable = (props, ref)=>{
const nativeProps = (0, _reactutilities.getPartitionedNativeProps)({
props,
primarySlotTagName: 'input',
excludedPropNames: [
'defaultValue',
'max',
'min',
'onChange',
'value'
]
});
const { value, displayValue, defaultValue, min, max, step = 1, stepPage = 1, precision: precisionFromProps, onChange, root, input, incrementButton, decrementButton } = props;
const precision = _react.useMemo(()=>{
return precisionFromProps !== null && precisionFromProps !== void 0 ? precisionFromProps : Math.max((0, _index.calculatePrecision)(step), 0);
}, [
precisionFromProps,
step
]);
const [currentValue, setCurrentValue] = (0, _reactutilities.useControllableState)({
state: value,
defaultState: defaultValue,
initialState: 0
});
const inputRef = _react.useRef(null);
const isControlled = value !== undefined;
const [textValue, setTextValue] = _react.useState(undefined);
const [keyboardSpinState, setKeyboardSpinState] = _react.useState('rest');
const internalState = _react.useRef({
value: currentValue,
spinState: 'rest',
spinTime: 0,
spinDelay: DEFAULT_SPIN_DELAY_MS,
atBound: currentValue !== null ? (0, _index.getBound)((0, _index.precisionRound)(currentValue, precision), min, max) : 'none'
});
const [setStepTimeout, clearStepTimeout] = (0, _reactutilities.useTimeout)();
const stepValue = (e, direction, startFrom)=>{
let startValue = internalState.current.value;
if (startFrom) {
const num = parseFloat(startFrom);
if (!isNaN(num)) {
startValue = num;
}
}
const val = startValue;
const dir = direction === 'up' || direction === 'upPage' ? 1 : -1;
const stepSize = direction === 'upPage' || direction === 'downPage' ? stepPage : step;
if (val === null) {
const stepStart = min === undefined ? 0 : min;
const nullStep = (0, _index.clamp)(stepStart + stepSize * dir, min, max);
commit(e, nullStep);
return;
}
let newValue = val + stepSize * dir;
if (!Number.isNaN(newValue)) {
newValue = (0, _index.clamp)(newValue, min, max);
}
commit(e, newValue);
if (internalState.current.spinState !== 'rest') {
setStepTimeout(()=>{
// Ease the step speed a bit
internalState.current.spinTime += internalState.current.spinDelay;
internalState.current.spinDelay = lerp(DEFAULT_SPIN_DELAY_MS, MIN_SPIN_DELAY_MS, internalState.current.spinTime / MAX_SPIN_TIME_MS);
stepValue(e, direction);
}, internalState.current.spinDelay);
}
};
const handleInputChange = (e)=>{
if (!internalState.current.previousTextValue) {
internalState.current.previousTextValue = textValue !== null && textValue !== void 0 ? textValue : String(currentValue);
}
const newValue = e.target.value;
setTextValue(newValue);
if (inputRef.current) {
// we need to set this here using the IDL attribute directly, because otherwise the timing of the ARIA value update
// is not in sync with the user-entered native input value, and some screen readers end up reading the wrong value.
// eslint-disable-next-line react-compiler/react-compiler
inputRef.current.ariaValueNow = newValue;
}
};
const handleIncrementMouseDown = (e)=>{
commit(e, currentValue, textValue);
internalState.current.spinState = 'up';
stepValue(e, 'up');
};
const handleDecrementMouseDown = (e)=>{
commit(e, currentValue, textValue);
internalState.current.spinState = 'down';
stepValue(e, 'down');
};
const handleStepMouseUpOrLeave = (e)=>{
clearStepTimeout();
internalState.current.spinState = 'rest';
internalState.current.spinDelay = DEFAULT_SPIN_DELAY_MS;
internalState.current.spinTime = 0;
};
const handleBlur = (e)=>{
commit(e, currentValue, textValue);
internalState.current.previousTextValue = undefined;
};
const handleKeyDown = (e)=>{
let nextKeyboardSpinState = 'rest';
if (e.currentTarget.readOnly) {
return;
}
if (e.key === _keyboardkeys.ArrowUp) {
stepValue(e, 'up', textValue);
nextKeyboardSpinState = 'up';
} else if (e.key === _keyboardkeys.ArrowDown) {
stepValue(e, 'down', textValue);
nextKeyboardSpinState = 'down';
} else if (e.key === _keyboardkeys.PageUp) {
e.preventDefault();
stepValue(e, 'upPage', textValue);
nextKeyboardSpinState = 'up';
} else if (e.key === _keyboardkeys.PageDown) {
e.preventDefault();
stepValue(e, 'downPage', textValue);
nextKeyboardSpinState = 'down';
} else if (!e.shiftKey && e.key === _keyboardkeys.Home && min !== undefined) {
commit(e, min);
nextKeyboardSpinState = 'down';
} else if (!e.shiftKey && e.key === _keyboardkeys.End && max !== undefined) {
commit(e, max);
nextKeyboardSpinState = 'up';
} else if (e.key === _keyboardkeys.Enter) {
commit(e, currentValue, textValue);
internalState.current.previousTextValue = undefined;
} else if (e.key === _keyboardkeys.Escape) {
if (internalState.current.previousTextValue) {
setTextValue(undefined);
internalState.current.previousTextValue = undefined;
}
}
if (keyboardSpinState !== nextKeyboardSpinState) {
setKeyboardSpinState(nextKeyboardSpinState);
}
};
const handleKeyUp = (e)=>{
if (keyboardSpinState !== 'rest') {
setKeyboardSpinState('rest');
internalState.current.spinState = 'rest';
}
};
const commit = (e, newValue, newDisplayValue)=>{
const valueChanged = newValue !== undefined && currentValue !== newValue;
const displayValueChanged = newDisplayValue !== undefined && internalState.current.previousTextValue !== undefined && internalState.current.previousTextValue !== newDisplayValue;
let roundedValue;
if (valueChanged) {
roundedValue = (0, _index.precisionRound)(newValue, precision);
setCurrentValue(roundedValue);
internalState.current.value = roundedValue;
} else if (displayValueChanged && !isControlled) {
const nextValue = parseFloat(newDisplayValue);
if (!isNaN(nextValue)) {
setCurrentValue((0, _index.precisionRound)(nextValue, precision));
internalState.current.value = (0, _index.precisionRound)(nextValue, precision);
}
}
if (valueChanged || displayValueChanged) {
onChange === null || onChange === void 0 ? void 0 : onChange(e, {
value: roundedValue,
displayValue: newDisplayValue
});
}
setTextValue(undefined);
};
let valueToDisplay;
if (textValue !== undefined) {
valueToDisplay = textValue;
} else if (value === null || currentValue === null) {
valueToDisplay = displayValue !== null && displayValue !== void 0 ? displayValue : '';
internalState.current.value = null;
internalState.current.atBound = 'none';
} else {
const roundedValue = (0, _index.precisionRound)(currentValue, precision);
internalState.current.value = roundedValue;
internalState.current.atBound = (0, _index.getBound)(roundedValue, min, max);
if (isControlled) {
valueToDisplay = displayValue !== null && displayValue !== void 0 ? displayValue : String(roundedValue);
} else {
valueToDisplay = String(roundedValue);
}
}
const state = {
spinState: keyboardSpinState,
atBound: internalState.current.atBound,
components: {
root: 'span',
input: 'input',
incrementButton: 'button',
decrementButton: 'button'
},
root: _reactutilities.slot.always(root, {
defaultProps: nativeProps.root,
elementType: 'span'
}),
input: _reactutilities.slot.always(input, {
defaultProps: {
autoComplete: 'off',
role: 'spinbutton',
type: 'text',
...nativeProps.primary
},
elementType: 'input'
}),
incrementButton: _reactutilities.slot.always(incrementButton, {
defaultProps: {
tabIndex: -1,
disabled: nativeProps.primary.readOnly || nativeProps.primary.disabled || internalState.current.atBound === 'max' || internalState.current.atBound === 'both',
'aria-label': 'Increment value',
type: 'button'
},
elementType: 'button'
}),
decrementButton: _reactutilities.slot.always(decrementButton, {
defaultProps: {
tabIndex: -1,
disabled: nativeProps.primary.readOnly || nativeProps.primary.disabled || internalState.current.atBound === 'min' || internalState.current.atBound === 'both',
'aria-label': 'Decrement value',
type: 'button'
},
elementType: 'button'
})
};
state.input.value = valueToDisplay;
state.input.ref = (0, _reactutilities.useMergedRefs)(inputRef, ref);
state.input['aria-valuemin'] = min;
state.input['aria-valuemax'] = max;
var _internalState_current_value;
state.input['aria-valuenow'] = (_internalState_current_value = internalState.current.value) !== null && _internalState_current_value !== void 0 ? _internalState_current_value : undefined;
var _state_input_ariavaluetext;
state.input['aria-valuetext'] = (_state_input_ariavaluetext = state.input['aria-valuetext']) !== null && _state_input_ariavaluetext !== void 0 ? _state_input_ariavaluetext : value !== undefined && displayValue || undefined;
state.input.onChange = (0, _reactutilities.mergeCallbacks)(state.input.onChange, handleInputChange);
state.input.onInput = (0, _reactutilities.mergeCallbacks)(state.input.onInput, handleInputChange);
state.input.onBlur = (0, _reactutilities.mergeCallbacks)(state.input.onBlur, handleBlur);
state.input.onKeyDown = (0, _reactutilities.mergeCallbacks)(state.input.onKeyDown, handleKeyDown);
state.input.onKeyUp = (0, _reactutilities.mergeCallbacks)(state.input.onKeyUp, handleKeyUp);
state.incrementButton.onMouseDown = (0, _reactutilities.mergeCallbacks)(handleIncrementMouseDown, state.incrementButton.onMouseDown);
state.incrementButton.onMouseUp = (0, _reactutilities.mergeCallbacks)(state.incrementButton.onMouseUp, handleStepMouseUpOrLeave);
state.incrementButton.onMouseLeave = (0, _reactutilities.mergeCallbacks)(state.incrementButton.onMouseLeave, handleStepMouseUpOrLeave);
state.decrementButton.onMouseDown = (0, _reactutilities.mergeCallbacks)(handleDecrementMouseDown, state.decrementButton.onMouseDown);
state.decrementButton.onMouseUp = (0, _reactutilities.mergeCallbacks)(state.decrementButton.onMouseUp, handleStepMouseUpOrLeave);
state.decrementButton.onMouseLeave = (0, _reactutilities.mergeCallbacks)(state.decrementButton.onMouseLeave, handleStepMouseUpOrLeave);
return state;
};
const useSpinButton_unstable = (props, ref)=>{
var _state_incrementButton, _state_decrementButton;
// Merge props from surrounding <Field>, if any
props = (0, _reactfield.useFieldControlProps_unstable)(props, {
supportsLabelFor: true,
supportsRequired: true
});
const overrides = (0, _reactsharedcontexts.useOverrides_unstable)();
var _overrides_inputDefaultAppearance;
const { appearance = (_overrides_inputDefaultAppearance = overrides.inputDefaultAppearance) !== null && _overrides_inputDefaultAppearance !== void 0 ? _overrides_inputDefaultAppearance : 'outline', size = 'medium', ...baseProps } = props;
const state = useSpinButtonBase_unstable(baseProps, ref);
var _children;
(_children = (_state_incrementButton = state.incrementButton).children) !== null && _children !== void 0 ? _children : _state_incrementButton.children = /*#__PURE__*/ _react.createElement(_reacticons.ChevronUp16Regular, null);
var _children1;
(_children1 = (_state_decrementButton = state.decrementButton).children) !== null && _children1 !== void 0 ? _children1 : _state_decrementButton.children = /*#__PURE__*/ _react.createElement(_reacticons.ChevronDown16Regular, null);
return {
...state,
appearance,
size
};
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,443 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
spinButtonClassNames: function() {
return spinButtonClassNames;
},
useSpinButtonStyles_unstable: function() {
return useSpinButtonStyles_unstable;
}
});
const _react = require("@griffel/react");
const spinButtonClassNames = {
root: 'fui-SpinButton',
input: 'fui-SpinButton__input',
incrementButton: 'fui-SpinButton__incrementButton',
decrementButton: 'fui-SpinButton__decrementButton'
};
const spinButtonExtraClassNames = {
buttonActive: 'fui-SpinButton__button_active'
};
const fieldHeights = {
small: '24px',
medium: '32px'
};
const useRootClassName = /*#__PURE__*/ (0, _react.__resetStyles)("r109xulx", "r1h2jnch", {
r: [
".r109xulx{display:inline-grid;grid-template-columns:1fr 24px;grid-template-rows:1fr 1fr;column-gap:var(--spacingHorizontalXS);row-gap:0;position:relative;isolation:isolate;vertical-align:middle;background-color:var(--colorNeutralBackground1);min-height:32px;padding:0 0 0 var(--spacingHorizontalMNudge);border-radius:var(--borderRadiusMedium);}",
".r109xulx::before{content:\"\";box-sizing:border-box;position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;z-index:10;border:1px solid var(--colorNeutralStroke1);border-bottom-color:var(--colorNeutralStrokeAccessible);border-radius:var(--borderRadiusMedium);}",
".r109xulx::after{box-sizing:border-box;content:\"\";position:absolute;right:0;bottom:0;left:0;z-index:20;height:max(2px, var(--borderRadiusMedium));border-bottom-left-radius:var(--borderRadiusMedium);border-bottom-right-radius:var(--borderRadiusMedium);border-bottom:2px solid var(--colorCompoundBrandStroke);clip-path:inset(calc(100% - 2px) 0 0 0);transform:scaleX(0);transition-property:transform;transition-duration:var(--durationUltraFast);transition-delay:var(--curveAccelerateMid);}",
".r109xulx:focus-within::after{transform:scaleX(1);transition-property:transform;transition-duration:var(--durationNormal);transition-delay:var(--curveDecelerateMid);}",
".r109xulx:focus-within:active::after{border-bottom-color:var(--colorCompoundBrandStrokePressed);}",
".r109xulx:focus-within{outline:2px solid transparent;}",
".r1h2jnch{display:inline-grid;grid-template-columns:1fr 24px;grid-template-rows:1fr 1fr;column-gap:var(--spacingHorizontalXS);row-gap:0;position:relative;isolation:isolate;vertical-align:middle;background-color:var(--colorNeutralBackground1);min-height:32px;padding:0 var(--spacingHorizontalMNudge) 0 0;border-radius:var(--borderRadiusMedium);}",
".r1h2jnch::before{content:\"\";box-sizing:border-box;position:absolute;top:0;left:0;bottom:0;right:0;pointer-events:none;z-index:10;border:1px solid var(--colorNeutralStroke1);border-bottom-color:var(--colorNeutralStrokeAccessible);border-radius:var(--borderRadiusMedium);}",
".r1h2jnch::after{box-sizing:border-box;content:\"\";position:absolute;left:0;bottom:0;right:0;z-index:20;height:max(2px, var(--borderRadiusMedium));border-bottom-right-radius:var(--borderRadiusMedium);border-bottom-left-radius:var(--borderRadiusMedium);border-bottom:2px solid var(--colorCompoundBrandStroke);clip-path:inset(calc(100% - 2px) 0 0 0);transform:scaleX(0);transition-property:transform;transition-duration:var(--durationUltraFast);transition-delay:var(--curveAccelerateMid);}",
".r1h2jnch:focus-within::after{transform:scaleX(1);transition-property:transform;transition-duration:var(--durationNormal);transition-delay:var(--curveDecelerateMid);}",
".r1h2jnch:focus-within:active::after{border-bottom-color:var(--colorCompoundBrandStrokePressed);}",
".r1h2jnch:focus-within{outline:2px solid transparent;}"
],
s: [
"@media screen and (prefers-reduced-motion: reduce){.r109xulx::after{transition-duration:0.01ms;transition-delay:0.01ms;}}",
"@media screen and (prefers-reduced-motion: reduce){.r109xulx:focus-within::after{transition-duration:0.01ms;transition-delay:0.01ms;}}",
"@media screen and (prefers-reduced-motion: reduce){.r1h2jnch::after{transition-duration:0.01ms;transition-delay:0.01ms;}}",
"@media screen and (prefers-reduced-motion: reduce){.r1h2jnch:focus-within::after{transition-duration:0.01ms;transition-delay:0.01ms;}}"
]
});
const useRootStyles = /*#__PURE__*/ (0, _react.__styles)({
small: {
sshi5w: "f1pha7fy",
Bahqtrf: "fk6fouc",
Be2twd7: "fy9rknc",
Bhrd7zp: "figsok6",
Bg96gwp: "fwrc4pm",
uwmqm3: [
"f1f5gg8d",
"f1vdfbxk"
]
},
medium: {},
outline: {},
outlineInteractive: {
Bo3r8zu: "f1w2y1rc",
Hpvxnh: [
"f1gofhvl",
"f18htlvq"
],
Bx11ytk: "ffcnd28",
B1rg0w0: [
"f18htlvq",
"f1gofhvl"
],
Bsg1tlv: "f6lmxco",
Brjw370: [
"fcoc0mf",
"f15r4wkl"
],
xcfy85: "f1ipdth8",
Bcc6kan: [
"f15r4wkl",
"fcoc0mf"
]
},
underline: {
B0qfbqy: "f1o236ok",
B4f6apu: [
"faeg28l",
"f64aojp"
],
y0oebl: "fdw6hkg",
uvfttm: [
"f64aojp",
"faeg28l"
],
r59vdv: 0,
Budzafs: 0,
ck0cow: 0,
n07z76: 0,
Gng75u: "f1xyh2jw"
},
underlineInteractive: {
Bx11ytk: "ffcnd28",
xcfy85: "f1ipdth8",
d9w3h3: 0,
B3778ie: 0,
B4j8arr: 0,
Bl18szs: 0,
Blrzh8d: "fkp7w9h"
},
filled: {
Bcgcnre: 0,
Bqjgrrk: 0,
qa3bma: 0,
y0oebl: 0,
Biqmznv: 0,
Bm6vgfq: 0,
Bbv0w2i: 0,
uvfttm: 0,
eqrjj: 0,
Bk5zm6e: 0,
m598lv: 0,
B4f6apu: 0,
ydt019: 0,
Bq4z7u6: 0,
Bdkvgpv: 0,
B0qfbqy: 0,
kj8mxx: "f1kc0wz4"
},
"filled-darker": {
De3pzq: "f16xq7d1"
},
"filled-lighter": {
De3pzq: "fxugw4r"
},
filledInteractive: {
B05mzqr: "f1xqt08",
tb9y6h: [
"fzt5lgo",
"f8tv3r9"
],
jcehpj: "fyhrops",
B23o0hn: [
"f8tv3r9",
"fzt5lgo"
]
},
invalid: {
emecyz: "fl48pg9",
lz0pba: [
"f1a168p3",
"f1pvdymy"
],
Bo1k74p: "f11knvgl",
Ba322q7: [
"f1pvdymy",
"f1a168p3"
]
},
disabled: {
Bceei9c: "fdrzuqr",
De3pzq: "f1c21dwh",
Bq4z7u6: "f1a0lfh7",
Bk5zm6e: [
"f1p2ejm6",
"fmzytvz"
],
Bqjgrrk: "fas2e61",
Bm6vgfq: [
"fmzytvz",
"f1p2ejm6"
],
Bvljrlq: "f1p5b8em",
Cqojjj: [
"fs6f9xf",
"f11b7h5x"
],
G3zxag: "f1vrn6tw",
H8270r: [
"f11b7h5x",
"fs6f9xf"
]
}
}, {
d: [
".f1pha7fy{min-height:24px;}",
".fk6fouc{font-family:var(--fontFamilyBase);}",
".fy9rknc{font-size:var(--fontSizeBase200);}",
".figsok6{font-weight:var(--fontWeightRegular);}",
".fwrc4pm{line-height:var(--lineHeightBase200);}",
".f1f5gg8d{padding-left:var(--spacingHorizontalS);}",
".f1vdfbxk{padding-right:var(--spacingHorizontalS);}",
".f1o236ok::before{border-top-width:0;}",
".faeg28l::before{border-right-width:0;}",
".f64aojp::before{border-left-width:0;}",
".fdw6hkg::before{border-bottom-width:1px;}",
[
".f1xyh2jw::before{border-radius:var(--borderRadiusNone);}",
{
p: -1
}
],
[
".fkp7w9h::after{border-radius:var(--borderRadiusNone);}",
{
p: -1
}
],
[
".f1kc0wz4::before{border:1px solid var(--colorTransparentStroke);}",
{
p: -2
}
],
".f16xq7d1{background-color:var(--colorNeutralBackground3);}",
".fxugw4r{background-color:var(--colorNeutralBackground1);}",
".fl48pg9:not(:focus-within)::before,.fl48pg9:hover:not(:focus-within)::before{border-top-color:var(--colorPaletteRedBorder2);}",
".f1a168p3:not(:focus-within)::before,.f1a168p3:hover:not(:focus-within)::before{border-right-color:var(--colorPaletteRedBorder2);}",
".f1pvdymy:not(:focus-within)::before,.f1pvdymy:hover:not(:focus-within)::before{border-left-color:var(--colorPaletteRedBorder2);}",
".f11knvgl:not(:focus-within)::before,.f11knvgl:hover:not(:focus-within)::before{border-bottom-color:var(--colorPaletteRedBorder2);}",
".fdrzuqr{cursor:not-allowed;}",
".f1c21dwh{background-color:var(--colorTransparentBackground);}",
".f1a0lfh7::before{border-top-color:var(--colorNeutralStrokeDisabled);}",
".f1p2ejm6::before{border-right-color:var(--colorNeutralStrokeDisabled);}",
".fmzytvz::before{border-left-color:var(--colorNeutralStrokeDisabled);}",
".fas2e61::before{border-bottom-color:var(--colorNeutralStrokeDisabled);}"
],
h: [
".f1w2y1rc:hover::before{border-top-color:var(--colorNeutralStroke1Hover);}",
".f1gofhvl:hover::before{border-right-color:var(--colorNeutralStroke1Hover);}",
".f18htlvq:hover::before{border-left-color:var(--colorNeutralStroke1Hover);}",
".ffcnd28:hover::before{border-bottom-color:var(--colorNeutralStrokeAccessibleHover);}",
".f1xqt08:hover::before,.f1xqt08:focus-within::before{border-top-color:var(--colorTransparentStrokeInteractive);}",
".fzt5lgo:hover::before,.fzt5lgo:focus-within::before{border-right-color:var(--colorTransparentStrokeInteractive);}",
".f8tv3r9:hover::before,.f8tv3r9:focus-within::before{border-left-color:var(--colorTransparentStrokeInteractive);}",
".fyhrops:hover::before,.fyhrops:focus-within::before{border-bottom-color:var(--colorTransparentStrokeInteractive);}"
],
a: [
".f6lmxco:active::before,.f6lmxco:focus-within::before{border-top-color:var(--colorNeutralStroke1Pressed);}",
".fcoc0mf:active::before,.fcoc0mf:focus-within::before{border-right-color:var(--colorNeutralStroke1Pressed);}",
".f15r4wkl:active::before,.f15r4wkl:focus-within::before{border-left-color:var(--colorNeutralStroke1Pressed);}",
".f1ipdth8:active::before,.f1ipdth8:focus-within::before{border-bottom-color:var(--colorNeutralStrokeAccessiblePressed);}"
],
m: [
[
"@media (forced-colors: active){.f1p5b8em::before{border-top-color:GrayText;}}",
{
m: "(forced-colors: active)"
}
],
[
"@media (forced-colors: active){.f11b7h5x::before{border-left-color:GrayText;}.fs6f9xf::before{border-right-color:GrayText;}}",
{
m: "(forced-colors: active)"
}
],
[
"@media (forced-colors: active){.f1vrn6tw::before{border-bottom-color:GrayText;}}",
{
m: "(forced-colors: active)"
}
]
]
});
const useInputClassName = /*#__PURE__*/ (0, _react.__resetStyles)("r1ljrqje", null, [
".r1ljrqje{grid-column-start:1;grid-column-end:2;grid-row-start:1;grid-row-end:3;outline-style:none;border:0;padding:0;color:var(--colorNeutralForeground1);background-color:transparent;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;width:100%;}",
".r1ljrqje::-webkit-input-placeholder{color:var(--colorNeutralForeground4);opacity:1;}",
".r1ljrqje::-moz-placeholder{color:var(--colorNeutralForeground4);opacity:1;}",
".r1ljrqje::placeholder{color:var(--colorNeutralForeground4);opacity:1;}"
]);
const useInputStyles = /*#__PURE__*/ (0, _react.__styles)({
disabled: {
sj55zd: "f1s2aq7o",
Bceei9c: "fdrzuqr",
De3pzq: "f1c21dwh",
yvdlaj: "fahhnxm"
}
}, {
d: [
".f1s2aq7o{color:var(--colorNeutralForegroundDisabled);}",
".fdrzuqr{cursor:not-allowed;}",
".f1c21dwh{background-color:var(--colorTransparentBackground);}",
".fahhnxm::-webkit-input-placeholder{color:var(--colorNeutralForegroundDisabled);}",
".fahhnxm::-moz-placeholder{color:var(--colorNeutralForegroundDisabled);}"
]
});
const useBaseButtonClassName = /*#__PURE__*/ (0, _react.__resetStyles)("r1g4chgs", null, [
".r1g4chgs{display:inline-flex;width:24px;align-items:center;justify-content:center;border:0;position:absolute;outline-style:none;height:16px;background-color:transparent;color:var(--colorNeutralForeground3);grid-column-start:2;border-radius:0;padding:0 5px 0 5px;}",
".r1g4chgs:active{outline-style:none;}",
".r1g4chgs:enabled:hover{cursor:pointer;color:var(--colorNeutralForeground3Hover);background-color:var(--colorSubtleBackgroundHover);}",
".r1g4chgs:enabled:active{color:var(--colorNeutralForeground3Pressed);background-color:var(--colorSubtleBackgroundPressed);}",
".r1g4chgs:enabled.fui-SpinButton__button_active{color:var(--colorNeutralForeground3Pressed);background-color:var(--colorSubtleBackgroundPressed);}",
".r1g4chgs:disabled{cursor:not-allowed;color:var(--colorNeutralForegroundDisabled);}"
]);
const useButtonStyles = /*#__PURE__*/ (0, _react.__styles)({
increment: {
Ijaq50: "f16hsg94",
B7oj6ja: [
"f1jar5jt",
"fyu767a"
],
z8tnut: "f10ra9hq",
Byoj8tv: "f1brlhvm"
},
decrement: {
Ijaq50: "faunodf",
Bbmb7ep: [
"f1aa9q02",
"f16jpd5f"
],
z8tnut: "f1sl3k7w",
Byoj8tv: "f1y2xyjm"
},
incrementButtonSmall: {
Byoj8tv: 0,
uwmqm3: 0,
z189sj: 0,
z8tnut: 0,
B0ocmuz: [
"f4lv8q1",
"fm3uwd2"
],
Bqenvij: "fvblgha"
},
decrementButtonSmall: {
Byoj8tv: 0,
uwmqm3: 0,
z189sj: 0,
z8tnut: 0,
B0ocmuz: [
"f1q86st8",
"frkrfqj"
],
Bqenvij: "fvblgha"
},
outline: {},
underline: {
De3pzq: "f3rmtva",
sj55zd: "f11d4kpn",
r4wkhp: "f1no7wuu",
B95qlz1: "f1bifk9c",
p743kt: "fp1zg4s",
B7xitij: "fo6hitd",
B6siaa6: "f1wiab75",
Ba9qmo4: "fj9zm5z",
Dyrjrp: "f1cqwcg4"
},
"filled-darker": {
De3pzq: "f3rmtva",
sj55zd: "f11d4kpn",
r4wkhp: "f1no7wuu",
B95qlz1: "fwwxidx",
p743kt: "fp1zg4s",
B7xitij: "f14i52sd",
B6siaa6: "f1wiab75",
Ba9qmo4: "fwry2ka",
Dyrjrp: "f1cqwcg4"
},
"filled-lighter": {
De3pzq: "f3rmtva",
sj55zd: "f11d4kpn",
r4wkhp: "f1no7wuu",
B95qlz1: "f1yywxnv",
drw0cw: "fzaa11h",
idzz8t: "f4fpmm9",
Dyrjrp: "f1cqwcg4"
}
}, {
d: [
".f16hsg94{grid-row-start:1;}",
".f1jar5jt{border-top-right-radius:var(--borderRadiusMedium);}",
".fyu767a{border-top-left-radius:var(--borderRadiusMedium);}",
".f10ra9hq{padding-top:4px;}",
".f1brlhvm{padding-bottom:1px;}",
".faunodf{grid-row-start:2;}",
".f1aa9q02{border-bottom-right-radius:var(--borderRadiusMedium);}",
".f16jpd5f{border-bottom-left-radius:var(--borderRadiusMedium);}",
".f1sl3k7w{padding-top:1px;}",
".f1y2xyjm{padding-bottom:4px;}",
[
".f4lv8q1{padding:3px 6px 0px 4px;}",
{
p: -1
}
],
[
".fm3uwd2{padding:3px 4px 0px 6px;}",
{
p: -1
}
],
".fvblgha{height:12px;}",
[
".f1q86st8{padding:0px 6px 3px 4px;}",
{
p: -1
}
],
[
".frkrfqj{padding:0px 4px 3px 6px;}",
{
p: -1
}
],
".f3rmtva{background-color:transparent;}",
".f11d4kpn{color:var(--colorNeutralForeground3);}",
".f1no7wuu:enabled:hover{color:var(--colorNeutralForeground3Hover);}",
".f1bifk9c:enabled:hover{background-color:var(--colorSubtleBackgroundHover);}",
".fp1zg4s:enabled:active{color:var(--colorNeutralForeground3Pressed);}",
".fo6hitd:enabled:active{background-color:var(--colorSubtleBackgroundPressed);}",
".f1wiab75:enabled.fui-SpinButton__button_active{color:var(--colorNeutralForeground3Pressed);}",
".fj9zm5z:enabled.fui-SpinButton__button_active{background-color:var(--colorSubtleBackgroundPressed);}",
".f1cqwcg4:disabled{color:var(--colorNeutralForegroundDisabled);}",
".fwwxidx:enabled:hover{background-color:var(--colorNeutralBackground3Hover);}",
".f14i52sd:enabled:active{background-color:var(--colorNeutralBackground3Pressed);}",
".fwry2ka:enabled.fui-SpinButton__button_active{background-color:var(--colorNeutralBackground3Pressed);}",
".f1yywxnv:enabled:hover{background-color:var(--colorNeutralBackground1Hover);}",
".fzaa11h:enabled:active,.fzaa11h:enabled.fui-SpinButton__button_active{color:var(--colorNeutralForeground3Pressed);}",
".f4fpmm9:enabled:active,.f4fpmm9:enabled.fui-SpinButton__button_active{background-color:var(--colorNeutralBackground1Pressed);}"
]
});
const useSpinButtonStyles_unstable = (state)=>{
'use no memo';
const { appearance, spinState, size } = state;
const disabled = state.input.disabled;
const invalid = `${state.input['aria-invalid']}` === 'true';
const filled = appearance.startsWith('filled');
const rootStyles = useRootStyles();
const buttonStyles = useButtonStyles();
const inputStyles = useInputStyles();
state.root.className = (0, _react.mergeClasses)(spinButtonClassNames.root, useRootClassName(), rootStyles[size], rootStyles[appearance], filled && rootStyles.filled, !disabled && appearance === 'outline' && rootStyles.outlineInteractive, !disabled && appearance === 'underline' && rootStyles.underlineInteractive, !disabled && filled && rootStyles.filledInteractive, !disabled && invalid && rootStyles.invalid, disabled && rootStyles.disabled, state.root.className);
state.incrementButton.className = (0, _react.mergeClasses)(spinButtonClassNames.incrementButton, spinState === 'up' && `${spinButtonExtraClassNames.buttonActive}`, useBaseButtonClassName(), buttonStyles.increment, buttonStyles[appearance], size === 'small' && buttonStyles.incrementButtonSmall, state.incrementButton.className);
state.decrementButton.className = (0, _react.mergeClasses)(spinButtonClassNames.decrementButton, spinState === 'down' && `${spinButtonExtraClassNames.buttonActive}`, useBaseButtonClassName(), buttonStyles.decrement, buttonStyles[appearance], size === 'small' && buttonStyles.decrementButtonSmall, state.decrementButton.className);
state.input.className = (0, _react.mergeClasses)(spinButtonClassNames.input, useInputClassName(), disabled && inputStyles.disabled, state.input.className);
return state;
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,373 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
spinButtonClassNames: function() {
return spinButtonClassNames;
},
useSpinButtonStyles_unstable: function() {
return useSpinButtonStyles_unstable;
}
});
const _react = require("@griffel/react");
const _reacttheme = require("@fluentui/react-theme");
const spinButtonClassNames = {
root: 'fui-SpinButton',
input: 'fui-SpinButton__input',
incrementButton: 'fui-SpinButton__incrementButton',
decrementButton: 'fui-SpinButton__decrementButton'
};
const spinButtonExtraClassNames = {
buttonActive: 'fui-SpinButton__button_active'
};
const fieldHeights = {
small: '24px',
medium: '32px'
};
const useRootClassName = (0, _react.makeResetStyles)({
display: 'inline-grid',
gridTemplateColumns: `1fr 24px`,
gridTemplateRows: '1fr 1fr',
columnGap: _reacttheme.tokens.spacingHorizontalXS,
rowGap: 0,
position: 'relative',
isolation: 'isolate',
verticalAlign: 'middle',
backgroundColor: _reacttheme.tokens.colorNeutralBackground1,
minHeight: fieldHeights.medium,
padding: `0 0 0 ${_reacttheme.tokens.spacingHorizontalMNudge}`,
borderRadius: _reacttheme.tokens.borderRadiusMedium,
// Apply border styles on the ::before pseudo element.
// We cannot use ::after since that is used for selection.
// Using the pseudo element allows us to place the border
// above content in the component which ensures the buttons
// line up visually with the border as expected. Without this
// there is a bit of a gap which can become very noticeable
// at high zoom or when OS zoom levels are not divisible by 2
// (e.g., 150% on Windows in Firefox)
// This is most noticeable on the "outline" appearance which is
// also the default so it feels worth the extra ceremony to get right.
'::before': {
content: '""',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
pointerEvents: 'none',
zIndex: 10,
border: `1px solid ${_reacttheme.tokens.colorNeutralStroke1}`,
borderBottomColor: _reacttheme.tokens.colorNeutralStrokeAccessible,
borderRadius: _reacttheme.tokens.borderRadiusMedium
},
'::after': {
boxSizing: 'border-box',
content: '""',
position: 'absolute',
right: 0,
bottom: 0,
left: 0,
zIndex: 20,
// Maintaining the correct corner radius:
// Use the whole border-radius as the height and only put radii on the bottom corners.
// (Otherwise the radius would be automatically reduced to fit available space.)
// max() ensures the focus border still shows up even if someone sets tokens.borderRadiusMedium to 0.
height: `max(2px, ${_reacttheme.tokens.borderRadiusMedium})`,
borderBottomLeftRadius: _reacttheme.tokens.borderRadiusMedium,
borderBottomRightRadius: _reacttheme.tokens.borderRadiusMedium,
// Flat 2px border:
// By default borderBottom will cause little "horns" on the ends. The clipPath trims them off.
// (This could be done without trimming using `background: linear-gradient(...)`, but using
// borderBottom makes it easier for people to override the color if needed.)
borderBottom: `2px solid ${_reacttheme.tokens.colorCompoundBrandStroke}`,
clipPath: 'inset(calc(100% - 2px) 0 0 0)',
// Animation for focus OUT
transform: 'scaleX(0)',
transitionProperty: 'transform',
transitionDuration: _reacttheme.tokens.durationUltraFast,
transitionDelay: _reacttheme.tokens.curveAccelerateMid,
'@media screen and (prefers-reduced-motion: reduce)': {
transitionDuration: '0.01ms',
transitionDelay: '0.01ms'
}
},
':focus-within::after': {
// Animation for focus IN
transform: 'scaleX(1)',
transitionProperty: 'transform',
transitionDuration: _reacttheme.tokens.durationNormal,
transitionDelay: _reacttheme.tokens.curveDecelerateMid,
'@media screen and (prefers-reduced-motion: reduce)': {
transitionDuration: '0.01ms',
transitionDelay: '0.01ms'
}
},
':focus-within:active::after': {
// This is if the user clicks the field again while it's already focused
borderBottomColor: _reacttheme.tokens.colorCompoundBrandStrokePressed
},
':focus-within': {
outline: '2px solid transparent'
}
});
const useRootStyles = (0, _react.makeStyles)({
small: {
minHeight: fieldHeights.small,
..._reacttheme.typographyStyles.caption1,
paddingLeft: _reacttheme.tokens.spacingHorizontalS
},
medium: {},
outline: {},
outlineInteractive: {
':hover::before': {
..._react.shorthands.borderColor(_reacttheme.tokens.colorNeutralStroke1Hover),
borderBottomColor: _reacttheme.tokens.colorNeutralStrokeAccessibleHover
},
// DO NOT add a space between the selectors! It changes the behavior of make-styles.
':active,:focus-within': {
'::before': {
..._react.shorthands.borderColor(_reacttheme.tokens.colorNeutralStroke1Pressed),
borderBottomColor: _reacttheme.tokens.colorNeutralStrokeAccessiblePressed
}
}
},
underline: {
'::before': {
..._react.shorthands.borderWidth(0, 0, '1px', 0),
borderRadius: _reacttheme.tokens.borderRadiusNone
}
},
underlineInteractive: {
':hover::before': {
borderBottomColor: _reacttheme.tokens.colorNeutralStrokeAccessibleHover
},
// DO NOT add a space between the selectors! It changes the behavior of make-styles.
':active,:focus-within': {
'::before': {
borderBottomColor: _reacttheme.tokens.colorNeutralStrokeAccessiblePressed
}
},
'::after': {
borderRadius: _reacttheme.tokens.borderRadiusNone
}
},
filled: {
'::before': {
border: `1px solid ${_reacttheme.tokens.colorTransparentStroke}`
}
},
'filled-darker': {
backgroundColor: _reacttheme.tokens.colorNeutralBackground3
},
'filled-lighter': {
backgroundColor: _reacttheme.tokens.colorNeutralBackground1
},
filledInteractive: {
// DO NOT add a space between the selectors! It changes the behavior of make-styles.
':hover,:focus-within': {
'::before': {
// also handles pressed border color (:active)
..._react.shorthands.borderColor(_reacttheme.tokens.colorTransparentStrokeInteractive)
}
}
},
invalid: {
':not(:focus-within),:hover:not(:focus-within)': {
'::before': {
..._react.shorthands.borderColor(_reacttheme.tokens.colorPaletteRedBorder2)
}
}
},
disabled: {
cursor: 'not-allowed',
backgroundColor: _reacttheme.tokens.colorTransparentBackground,
'::before': {
..._react.shorthands.borderColor(_reacttheme.tokens.colorNeutralStrokeDisabled),
'@media (forced-colors: active)': {
..._react.shorthands.borderColor('GrayText')
}
}
}
});
const useInputClassName = (0, _react.makeResetStyles)({
gridColumnStart: '1',
gridColumnEnd: '2',
gridRowStart: '1',
gridRowEnd: '3',
outlineStyle: 'none',
border: '0',
padding: '0',
color: _reacttheme.tokens.colorNeutralForeground1,
// Use literal "transparent" (not from the theme) to always let the color from the root show through
backgroundColor: 'transparent',
fontFamily: 'inherit',
fontSize: 'inherit',
fontWeight: 'inherit',
lineHeight: 'inherit',
width: '100%',
'::placeholder': {
color: _reacttheme.tokens.colorNeutralForeground4,
opacity: 1
}
});
const useInputStyles = (0, _react.makeStyles)({
disabled: {
color: _reacttheme.tokens.colorNeutralForegroundDisabled,
cursor: 'not-allowed',
backgroundColor: _reacttheme.tokens.colorTransparentBackground,
'::placeholder': {
color: _reacttheme.tokens.colorNeutralForegroundDisabled
}
}
});
const useBaseButtonClassName = (0, _react.makeResetStyles)({
display: 'inline-flex',
width: '24px',
alignItems: 'center',
justifyContent: 'center',
border: '0',
position: 'absolute',
outlineStyle: 'none',
height: '16px',
// Use literal "transparent" (not from the theme) to always let the color from the root show through
backgroundColor: 'transparent',
color: _reacttheme.tokens.colorNeutralForeground3,
// common button layout
gridColumnStart: '2',
borderRadius: '0',
padding: '0 5px 0 5px',
':active': {
outlineStyle: 'none'
},
':enabled': {
':hover': {
cursor: 'pointer',
color: _reacttheme.tokens.colorNeutralForeground3Hover,
backgroundColor: _reacttheme.tokens.colorSubtleBackgroundHover
},
':active': {
color: _reacttheme.tokens.colorNeutralForeground3Pressed,
backgroundColor: _reacttheme.tokens.colorSubtleBackgroundPressed
},
[`&.${spinButtonExtraClassNames.buttonActive}`]: {
color: _reacttheme.tokens.colorNeutralForeground3Pressed,
backgroundColor: _reacttheme.tokens.colorSubtleBackgroundPressed
}
},
':disabled': {
cursor: 'not-allowed',
color: _reacttheme.tokens.colorNeutralForegroundDisabled
}
});
const useButtonStyles = (0, _react.makeStyles)({
increment: {
gridRowStart: '1',
borderTopRightRadius: _reacttheme.tokens.borderRadiusMedium,
paddingTop: '4px',
paddingBottom: '1px'
},
decrement: {
gridRowStart: '2',
borderBottomRightRadius: _reacttheme.tokens.borderRadiusMedium,
paddingTop: '1px',
paddingBottom: '4px'
},
// Padding values numbers don't align with design specs
// but visually the padding aligns.
// The icons are set in a 16x16px square but the artwork is inset from that
// so these padding values are computed by hand.
// Additionally the design uses fractional values so these are
// rounded to the nearest integer.
incrementButtonSmall: {
padding: '3px 6px 0px 4px',
height: '12px'
},
decrementButtonSmall: {
padding: '0px 6px 3px 4px',
height: '12px'
},
outline: {},
underline: {
backgroundColor: 'transparent',
color: _reacttheme.tokens.colorNeutralForeground3,
':enabled': {
':hover': {
color: _reacttheme.tokens.colorNeutralForeground3Hover,
backgroundColor: _reacttheme.tokens.colorSubtleBackgroundHover
},
':active': {
color: _reacttheme.tokens.colorNeutralForeground3Pressed,
backgroundColor: _reacttheme.tokens.colorSubtleBackgroundPressed
},
[`&.${spinButtonExtraClassNames.buttonActive}`]: {
color: _reacttheme.tokens.colorNeutralForeground3Pressed,
backgroundColor: _reacttheme.tokens.colorSubtleBackgroundPressed
}
},
':disabled': {
color: _reacttheme.tokens.colorNeutralForegroundDisabled
}
},
'filled-darker': {
backgroundColor: 'transparent',
color: _reacttheme.tokens.colorNeutralForeground3,
':enabled': {
':hover': {
color: _reacttheme.tokens.colorNeutralForeground3Hover,
backgroundColor: _reacttheme.tokens.colorNeutralBackground3Hover
},
':active': {
color: _reacttheme.tokens.colorNeutralForeground3Pressed,
backgroundColor: _reacttheme.tokens.colorNeutralBackground3Pressed
},
[`&.${spinButtonExtraClassNames.buttonActive}`]: {
color: _reacttheme.tokens.colorNeutralForeground3Pressed,
backgroundColor: _reacttheme.tokens.colorNeutralBackground3Pressed
}
},
':disabled': {
color: _reacttheme.tokens.colorNeutralForegroundDisabled
}
},
'filled-lighter': {
backgroundColor: 'transparent',
color: _reacttheme.tokens.colorNeutralForeground3,
':enabled': {
':hover': {
color: _reacttheme.tokens.colorNeutralForeground3Hover,
backgroundColor: _reacttheme.tokens.colorNeutralBackground1Hover
},
[`:active,&.${spinButtonExtraClassNames.buttonActive}`]: {
color: _reacttheme.tokens.colorNeutralForeground3Pressed,
backgroundColor: _reacttheme.tokens.colorNeutralBackground1Pressed
}
},
':disabled': {
color: _reacttheme.tokens.colorNeutralForegroundDisabled
}
}
});
const useSpinButtonStyles_unstable = (state)=>{
'use no memo';
const { appearance, spinState, size } = state;
const disabled = state.input.disabled;
const invalid = `${state.input['aria-invalid']}` === 'true';
const filled = appearance.startsWith('filled');
const rootStyles = useRootStyles();
const buttonStyles = useButtonStyles();
const inputStyles = useInputStyles();
state.root.className = (0, _react.mergeClasses)(spinButtonClassNames.root, useRootClassName(), rootStyles[size], rootStyles[appearance], filled && rootStyles.filled, !disabled && appearance === 'outline' && rootStyles.outlineInteractive, !disabled && appearance === 'underline' && rootStyles.underlineInteractive, !disabled && filled && rootStyles.filledInteractive, !disabled && invalid && rootStyles.invalid, disabled && rootStyles.disabled, state.root.className);
state.incrementButton.className = (0, _react.mergeClasses)(spinButtonClassNames.incrementButton, spinState === 'up' && `${spinButtonExtraClassNames.buttonActive}`, useBaseButtonClassName(), buttonStyles.increment, buttonStyles[appearance], size === 'small' && buttonStyles.incrementButtonSmall, state.incrementButton.className);
state.decrementButton.className = (0, _react.mergeClasses)(spinButtonClassNames.decrementButton, spinState === 'down' && `${spinButtonExtraClassNames.buttonActive}`, useBaseButtonClassName(), buttonStyles.decrement, buttonStyles[appearance], size === 'small' && buttonStyles.decrementButtonSmall, state.decrementButton.className);
state.input.className = (0, _react.mergeClasses)(spinButtonClassNames.input, useInputClassName(), disabled && inputStyles.disabled, state.input.className);
return state;
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
SpinButton: function() {
return _SpinButton.SpinButton;
},
renderSpinButton_unstable: function() {
return _SpinButton.renderSpinButton_unstable;
},
spinButtonClassNames: function() {
return _SpinButton.spinButtonClassNames;
},
useSpinButtonBase_unstable: function() {
return _SpinButton.useSpinButtonBase_unstable;
},
useSpinButtonStyles_unstable: function() {
return _SpinButton.useSpinButtonStyles_unstable;
},
useSpinButton_unstable: function() {
return _SpinButton.useSpinButton_unstable;
}
});
const _SpinButton = require("./SpinButton");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n SpinButton,\n renderSpinButton_unstable,\n spinButtonClassNames,\n useSpinButtonStyles_unstable,\n useSpinButtonBase_unstable,\n useSpinButton_unstable,\n} from './SpinButton';\nexport type {\n SpinButtonBaseProps,\n SpinButtonBaseState,\n SpinButtonOnChangeData,\n SpinButtonChangeEvent,\n SpinButtonProps,\n SpinButtonSlots,\n SpinButtonState,\n SpinButtonSpinState,\n SpinButtonBounds,\n} from './SpinButton';\n"],"names":["SpinButton","renderSpinButton_unstable","spinButtonClassNames","useSpinButtonStyles_unstable","useSpinButtonBase_unstable","useSpinButton_unstable"],"mappings":";;;;;;;;;;;;eACEA,sBAAU;;;eACVC,qCAAyB;;;eACzBC,gCAAoB;;;eAEpBE,sCAA0B;;;eAD1BD,wCAA4B;;;eAE5BE,kCAAsB;;;4BACjB,eAAe"}

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "clamp", {
enumerable: true,
get: function() {
return clamp;
}
});
const clamp = (value, min, max)=>{
let nextValue = value;
if (min !== undefined) {
if (max !== undefined && min > max) {
const error = new Error();
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.error([
`"min" value "${min}" is greater than "max" value "${max}".`,
'"min" must be less than or equal to "max".',
`Returning value "${value}".`,
error.stack
].join());
}
return value;
}
nextValue = Math.max(min, nextValue);
}
if (max !== undefined) {
nextValue = Math.min(max, nextValue);
}
return nextValue;
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/clamp.ts"],"sourcesContent":["export const clamp = (value: number, min?: number, max?: number): number => {\n let nextValue = value;\n if (min !== undefined) {\n if (max !== undefined && min > max) {\n const error = new Error();\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(\n [\n `\"min\" value \"${min}\" is greater than \"max\" value \"${max}\".`,\n '\"min\" must be less than or equal to \"max\".',\n `Returning value \"${value}\".`,\n error.stack,\n ].join(),\n );\n }\n return value;\n }\n\n nextValue = Math.max(min, nextValue);\n }\n\n if (max !== undefined) {\n nextValue = Math.min(max, nextValue);\n }\n\n return nextValue;\n};\n"],"names":["clamp","value","min","max","nextValue","undefined","error","Error","process","env","NODE_ENV","console","stack","join","Math"],"mappings":";;;;+BAAaA;;;;;;AAAN,cAAc,CAACC,OAAeC,KAAcC;IACjD,IAAIC,YAAYH;IAChB,IAAIC,QAAQG,WAAW;QACrB,IAAIF,QAAQE,aAAaH,MAAMC,KAAK;YAClC,MAAMG,QAAQ,IAAIC;YAClB,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzC,sCAAsC;gBACtCC,QAAQL,KAAK,CACX;oBACE,CAAC,aAAa,EAAEJ,IAAI,+BAA+B,EAAEC,IAAI,EAAE,CAAC;oBAC5D;oBACA,CAAC,iBAAiB,EAAEF,MAAM,EAAE,CAAC;oBAC7BK,MAAMM,KAAK;iBACZ,CAACC,IAAI;YAEV;YACA,OAAOZ;QACT;QAEAG,YAAYU,KAAKX,GAAG,CAACD,KAAKE;IAC5B;IAEA,IAAID,QAAQE,WAAW;QACrBD,YAAYU,KAAKZ,GAAG,CAACC,KAAKC;IAC5B;IAEA,OAAOA;AACT,EAAE"}

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "getBound", {
enumerable: true,
get: function() {
return getBound;
}
});
const getBound = (value, min, max)=>{
if (min !== undefined && value === min) {
if (max === min) {
return 'both';
}
return 'min';
} else if (max !== undefined && value === max) {
return 'max';
}
return 'none';
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/getBound.ts"],"sourcesContent":["import type { SpinButtonBounds } from '../SpinButton';\n\nexport const getBound = (value: number, min?: number, max?: number): SpinButtonBounds => {\n if (min !== undefined && value === min) {\n if (max === min) {\n return 'both';\n }\n return 'min';\n } else if (max !== undefined && value === max) {\n return 'max';\n }\n\n return 'none';\n};\n"],"names":["getBound","value","min","max","undefined"],"mappings":";;;;+BAEaA;;;;;;AAAN,iBAAiB,CAACC,OAAeC,KAAcC;IACpD,IAAID,QAAQE,aAAaH,UAAUC,KAAK;QACtC,IAAIC,QAAQD,KAAK;YACf,OAAO;QACT;QACA,OAAO;IACT,OAAO,IAAIC,QAAQC,aAAaH,UAAUE,KAAK;QAC7C,OAAO;IACT;IAEA,OAAO;AACT,EAAE"}

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
calculatePrecision: function() {
return _precision.calculatePrecision;
},
clamp: function() {
return _clamp.clamp;
},
getBound: function() {
return _getBound.getBound;
},
precisionRound: function() {
return _precision.precisionRound;
}
});
const _clamp = require("./clamp");
const _getBound = require("./getBound");
const _precision = require("./precision");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/index.ts"],"sourcesContent":["export { clamp } from './clamp';\nexport { getBound } from './getBound';\nexport { calculatePrecision, precisionRound } from './precision';\n"],"names":["clamp","getBound","calculatePrecision","precisionRound"],"mappings":";;;;;;;;;;;;eAESE,6BAAkB;;;eAFlBF,YAAK;;;eACLC,kBAAQ;;;eACYE,yBAAc;;;uBAFrB,UAAU;0BACP,aAAa;2BACa,cAAc"}

View File

@@ -0,0 +1,46 @@
/**
* Calculates a number's precision based on the number of trailing
* zeros if the number does not have a decimal indicated by a negative
* precision. Otherwise, it calculates the number of digits after
* the decimal point indicated by a positive precision.
* @param value - the value to determine the precision of
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
calculatePrecision: function() {
return calculatePrecision;
},
precisionRound: function() {
return precisionRound;
}
});
function calculatePrecision(value) {
/**
* Group 1:
* [1-9]([0]+$) matches trailing zeros
* Group 2:
* \.([0-9]*) matches all digits after a decimal point.
*/ const groups = /[1-9]([0]+$)|\.([0-9]*)/.exec(String(value));
if (!groups) {
return 0;
}
if (groups[1]) {
return -groups[1].length;
}
if (groups[2]) {
return groups[2].length;
}
return 0;
}
function precisionRound(value, precision, base = 10) {
const exp = base ** precision;
return Math.round(value * exp) / exp;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/precision.ts"],"sourcesContent":["/**\n * Calculates a number's precision based on the number of trailing\n * zeros if the number does not have a decimal indicated by a negative\n * precision. Otherwise, it calculates the number of digits after\n * the decimal point indicated by a positive precision.\n * @param value - the value to determine the precision of\n */\nexport function calculatePrecision(value: number | string): number {\n /**\n * Group 1:\n * [1-9]([0]+$) matches trailing zeros\n * Group 2:\n * \\.([0-9]*) matches all digits after a decimal point.\n */\n const groups = /[1-9]([0]+$)|\\.([0-9]*)/.exec(String(value));\n if (!groups) {\n return 0;\n }\n if (groups[1]) {\n return -groups[1].length;\n }\n if (groups[2]) {\n return groups[2].length;\n }\n return 0;\n}\n\n/**\n * Rounds a number to a certain level of precision. Accepts negative precision.\n * @param value - The value that is being rounded.\n * @param precision - The number of decimal places to round the number to\n */\nexport function precisionRound(value: number, precision: number, base: number = 10): number {\n const exp = base ** precision;\n return Math.round(value * exp) / exp;\n}\n"],"names":["calculatePrecision","value","groups","exec","String","length","precisionRound","precision","base","exp","Math","round"],"mappings":"AAAA;;;;;;CAMC,GACD;;;;;;;;;;;sBAAgBA;;;kBAyBAM;;;;AAzBT,SAASN,mBAAmBC,KAAsB;IACvD;;;;;GAKC,GACD,MAAMC,SAAS,0BAA0BC,IAAI,CAACC,OAAOH;IACrD,IAAI,CAACC,QAAQ;QACX,OAAO;IACT;IACA,IAAIA,MAAM,CAAC,EAAE,EAAE;QACb,OAAO,CAACA,MAAM,CAAC,EAAE,CAACG,MAAM;IAC1B;IACA,IAAIH,MAAM,CAAC,EAAE,EAAE;QACb,OAAOA,MAAM,CAAC,EAAE,CAACG,MAAM;IACzB;IACA,OAAO;AACT;AAOO,SAASC,eAAeL,KAAa,EAAEM,SAAiB,EAAEC,OAAe,EAAE;IAChF,MAAMC,MAAMD,QAAQD;IACpB,OAAOG,KAAKC,KAAK,CAACV,QAAQQ,OAAOA;AACnC"}

View File

@@ -0,0 +1 @@
export { SpinButton, renderSpinButton_unstable, spinButtonClassNames, useSpinButtonStyles_unstable, useSpinButtonBase_unstable, useSpinButton_unstable } from './components/SpinButton/index';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/SpinButton.ts"],"sourcesContent":["export type {\n SpinButtonBaseProps,\n SpinButtonBaseState,\n SpinButtonBounds,\n SpinButtonChangeEvent,\n SpinButtonOnChangeData,\n SpinButtonProps,\n SpinButtonSlots,\n SpinButtonSpinState,\n SpinButtonState,\n} from './components/SpinButton/index';\nexport {\n SpinButton,\n renderSpinButton_unstable,\n spinButtonClassNames,\n useSpinButtonStyles_unstable,\n useSpinButtonBase_unstable,\n useSpinButton_unstable,\n} from './components/SpinButton/index';\n"],"names":["SpinButton","renderSpinButton_unstable","spinButtonClassNames","useSpinButtonStyles_unstable","useSpinButtonBase_unstable","useSpinButton_unstable"],"mappings":"AAWA,SACEA,UAAU,EACVC,yBAAyB,EACzBC,oBAAoB,EACpBC,4BAA4B,EAC5BC,0BAA0B,EAC1BC,sBAAsB,QACjB,gCAAgC"}

View File

@@ -0,0 +1,15 @@
'use client';
import * as React from 'react';
import { useSpinButton_unstable } from './useSpinButton';
import { renderSpinButton_unstable } from './renderSpinButton';
import { useSpinButtonStyles_unstable } from './useSpinButtonStyles.styles';
import { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';
/**
* A SpinButton allows someone to incrementally adjust a value in small steps.
*/ export const SpinButton = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const state = useSpinButton_unstable(props, ref);
useSpinButtonStyles_unstable(state);
useCustomStyleHook_unstable('useSpinButtonStyles_unstable')(state);
return renderSpinButton_unstable(state);
});
SpinButton.displayName = 'SpinButton';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SpinButton/SpinButton.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useSpinButton_unstable } from './useSpinButton';\nimport { renderSpinButton_unstable } from './renderSpinButton';\nimport { useSpinButtonStyles_unstable } from './useSpinButtonStyles.styles';\nimport type { SpinButtonProps } from './SpinButton.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * A SpinButton allows someone to incrementally adjust a value in small steps.\n */\nexport const SpinButton: ForwardRefComponent<SpinButtonProps> = React.forwardRef((props, ref) => {\n const state = useSpinButton_unstable(props, ref);\n\n useSpinButtonStyles_unstable(state);\n\n useCustomStyleHook_unstable('useSpinButtonStyles_unstable')(state);\n\n return renderSpinButton_unstable(state);\n});\n\nSpinButton.displayName = 'SpinButton';\n"],"names":["React","useSpinButton_unstable","renderSpinButton_unstable","useSpinButtonStyles_unstable","useCustomStyleHook_unstable","SpinButton","forwardRef","props","ref","state","displayName"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,sBAAsB,QAAQ,kBAAkB;AACzD,SAASC,yBAAyB,QAAQ,qBAAqB;AAC/D,SAASC,4BAA4B,QAAQ,+BAA+B;AAG5E,SAASC,2BAA2B,QAAQ,kCAAkC;AAE9E;;CAEC,GACD,OAAO,MAAMC,2BAAmDL,MAAMM,UAAU,CAAC,CAACC,OAAOC;IACvF,MAAMC,QAAQR,uBAAuBM,OAAOC;IAE5CL,6BAA6BM;IAE7BL,4BAA4B,gCAAgCK;IAE5D,OAAOP,0BAA0BO;AACnC,GAAG;AAEHJ,WAAWK,WAAW,GAAG"}

View File

@@ -0,0 +1 @@
import * as React from 'react';

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
export { SpinButton } from './SpinButton';
export { renderSpinButton_unstable } from './renderSpinButton';
export { useSpinButtonBase_unstable, useSpinButton_unstable } from './useSpinButton';
export { spinButtonClassNames, useSpinButtonStyles_unstable } from './useSpinButtonStyles.styles';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SpinButton/index.ts"],"sourcesContent":["export { SpinButton } from './SpinButton';\nexport type {\n SpinButtonBaseProps,\n SpinButtonBaseState,\n SpinButtonBounds,\n SpinButtonChangeEvent,\n SpinButtonOnChangeData,\n SpinButtonProps,\n SpinButtonSlots,\n SpinButtonSpinState,\n SpinButtonState,\n} from './SpinButton.types';\nexport { renderSpinButton_unstable } from './renderSpinButton';\nexport { useSpinButtonBase_unstable, useSpinButton_unstable } from './useSpinButton';\nexport { spinButtonClassNames, useSpinButtonStyles_unstable } from './useSpinButtonStyles.styles';\n"],"names":["SpinButton","renderSpinButton_unstable","useSpinButtonBase_unstable","useSpinButton_unstable","spinButtonClassNames","useSpinButtonStyles_unstable"],"mappings":"AAAA,SAASA,UAAU,QAAQ,eAAe;AAY1C,SAASC,yBAAyB,QAAQ,qBAAqB;AAC/D,SAASC,0BAA0B,EAAEC,sBAAsB,QAAQ,kBAAkB;AACrF,SAASC,oBAAoB,EAAEC,4BAA4B,QAAQ,+BAA+B"}

View File

@@ -0,0 +1,14 @@
import { jsx as _jsx, jsxs as _jsxs } from "@fluentui/react-jsx-runtime/jsx-runtime";
import { assertSlots } from '@fluentui/react-utilities';
/**
* Render the final JSX of SpinButton
*/ export const renderSpinButton_unstable = (state)=>{
assertSlots(state);
return /*#__PURE__*/ _jsxs(state.root, {
children: [
/*#__PURE__*/ _jsx(state.input, {}),
/*#__PURE__*/ _jsx(state.incrementButton, {}),
/*#__PURE__*/ _jsx(state.decrementButton, {})
]
});
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SpinButton/renderSpinButton.tsx"],"sourcesContent":["/** @jsxRuntime automatic */\n/** @jsxImportSource @fluentui/react-jsx-runtime */\n\nimport { assertSlots } from '@fluentui/react-utilities';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport type { SpinButtonBaseState, SpinButtonSlots } from './SpinButton.types';\n\n/**\n * Render the final JSX of SpinButton\n */\nexport const renderSpinButton_unstable = (state: SpinButtonBaseState): JSXElement => {\n assertSlots<SpinButtonSlots>(state);\n\n return (\n <state.root>\n <state.input />\n <state.incrementButton />\n <state.decrementButton />\n </state.root>\n );\n};\n"],"names":["assertSlots","renderSpinButton_unstable","state","root","input","incrementButton","decrementButton"],"mappings":"AAAA,0BAA0B,GAC1B,iDAAiD;AAEjD,SAASA,WAAW,QAAQ,4BAA4B;AAIxD;;CAEC,GACD,OAAO,MAAMC,4BAA4B,CAACC;IACxCF,YAA6BE;IAE7B,qBACE,MAACA,MAAMC,IAAI;;0BACT,KAACD,MAAME,KAAK;0BACZ,KAACF,MAAMG,eAAe;0BACtB,KAACH,MAAMI,eAAe;;;AAG5B,EAAE"}

View File

@@ -0,0 +1,295 @@
'use client';
import * as React from 'react';
import { useFieldControlProps_unstable } from '@fluentui/react-field';
import { getPartitionedNativeProps, mergeCallbacks, useControllableState, useTimeout, slot, useMergedRefs } from '@fluentui/react-utilities';
import { ArrowUp, ArrowDown, End, Enter, Escape, Home, PageDown, PageUp } from '@fluentui/keyboard-keys';
import { calculatePrecision, precisionRound, getBound, clamp } from '../../utils/index';
import { ChevronUp16Regular, ChevronDown16Regular } from '@fluentui/react-icons';
import { useOverrides_unstable as useOverrides } from '@fluentui/react-shared-contexts';
const DEFAULT_SPIN_DELAY_MS = 150;
const MIN_SPIN_DELAY_MS = 80;
const MAX_SPIN_TIME_MS = 1000;
// This is here to give an ease for the mouse held down case.
// Exact easing it to be defined. Once it is we'll likely
// pull this out into a util function in the SpinButton package.
const lerp = (start, end, percent)=>start + (end - start) * percent;
/**
* Create the base state required to render SpinButton without design-specific props.
*
* @param props - props from this instance of SpinButton (without appearance/size)
* @param ref - reference to root HTMLElement of SpinButton
*/ export const useSpinButtonBase_unstable = (props, ref)=>{
const nativeProps = getPartitionedNativeProps({
props,
primarySlotTagName: 'input',
excludedPropNames: [
'defaultValue',
'max',
'min',
'onChange',
'value'
]
});
const { value, displayValue, defaultValue, min, max, step = 1, stepPage = 1, precision: precisionFromProps, onChange, root, input, incrementButton, decrementButton } = props;
const precision = React.useMemo(()=>{
return precisionFromProps !== null && precisionFromProps !== void 0 ? precisionFromProps : Math.max(calculatePrecision(step), 0);
}, [
precisionFromProps,
step
]);
const [currentValue, setCurrentValue] = useControllableState({
state: value,
defaultState: defaultValue,
initialState: 0
});
const inputRef = React.useRef(null);
const isControlled = value !== undefined;
const [textValue, setTextValue] = React.useState(undefined);
const [keyboardSpinState, setKeyboardSpinState] = React.useState('rest');
const internalState = React.useRef({
value: currentValue,
spinState: 'rest',
spinTime: 0,
spinDelay: DEFAULT_SPIN_DELAY_MS,
atBound: currentValue !== null ? getBound(precisionRound(currentValue, precision), min, max) : 'none'
});
const [setStepTimeout, clearStepTimeout] = useTimeout();
const stepValue = (e, direction, startFrom)=>{
let startValue = internalState.current.value;
if (startFrom) {
const num = parseFloat(startFrom);
if (!isNaN(num)) {
startValue = num;
}
}
const val = startValue;
const dir = direction === 'up' || direction === 'upPage' ? 1 : -1;
const stepSize = direction === 'upPage' || direction === 'downPage' ? stepPage : step;
if (val === null) {
const stepStart = min === undefined ? 0 : min;
const nullStep = clamp(stepStart + stepSize * dir, min, max);
commit(e, nullStep);
return;
}
let newValue = val + stepSize * dir;
if (!Number.isNaN(newValue)) {
newValue = clamp(newValue, min, max);
}
commit(e, newValue);
if (internalState.current.spinState !== 'rest') {
setStepTimeout(()=>{
// Ease the step speed a bit
internalState.current.spinTime += internalState.current.spinDelay;
internalState.current.spinDelay = lerp(DEFAULT_SPIN_DELAY_MS, MIN_SPIN_DELAY_MS, internalState.current.spinTime / MAX_SPIN_TIME_MS);
stepValue(e, direction);
}, internalState.current.spinDelay);
}
};
const handleInputChange = (e)=>{
if (!internalState.current.previousTextValue) {
internalState.current.previousTextValue = textValue !== null && textValue !== void 0 ? textValue : String(currentValue);
}
const newValue = e.target.value;
setTextValue(newValue);
if (inputRef.current) {
// we need to set this here using the IDL attribute directly, because otherwise the timing of the ARIA value update
// is not in sync with the user-entered native input value, and some screen readers end up reading the wrong value.
// eslint-disable-next-line react-compiler/react-compiler
inputRef.current.ariaValueNow = newValue;
}
};
const handleIncrementMouseDown = (e)=>{
commit(e, currentValue, textValue);
internalState.current.spinState = 'up';
stepValue(e, 'up');
};
const handleDecrementMouseDown = (e)=>{
commit(e, currentValue, textValue);
internalState.current.spinState = 'down';
stepValue(e, 'down');
};
const handleStepMouseUpOrLeave = (e)=>{
clearStepTimeout();
internalState.current.spinState = 'rest';
internalState.current.spinDelay = DEFAULT_SPIN_DELAY_MS;
internalState.current.spinTime = 0;
};
const handleBlur = (e)=>{
commit(e, currentValue, textValue);
internalState.current.previousTextValue = undefined;
};
const handleKeyDown = (e)=>{
let nextKeyboardSpinState = 'rest';
if (e.currentTarget.readOnly) {
return;
}
if (e.key === ArrowUp) {
stepValue(e, 'up', textValue);
nextKeyboardSpinState = 'up';
} else if (e.key === ArrowDown) {
stepValue(e, 'down', textValue);
nextKeyboardSpinState = 'down';
} else if (e.key === PageUp) {
e.preventDefault();
stepValue(e, 'upPage', textValue);
nextKeyboardSpinState = 'up';
} else if (e.key === PageDown) {
e.preventDefault();
stepValue(e, 'downPage', textValue);
nextKeyboardSpinState = 'down';
} else if (!e.shiftKey && e.key === Home && min !== undefined) {
commit(e, min);
nextKeyboardSpinState = 'down';
} else if (!e.shiftKey && e.key === End && max !== undefined) {
commit(e, max);
nextKeyboardSpinState = 'up';
} else if (e.key === Enter) {
commit(e, currentValue, textValue);
internalState.current.previousTextValue = undefined;
} else if (e.key === Escape) {
if (internalState.current.previousTextValue) {
setTextValue(undefined);
internalState.current.previousTextValue = undefined;
}
}
if (keyboardSpinState !== nextKeyboardSpinState) {
setKeyboardSpinState(nextKeyboardSpinState);
}
};
const handleKeyUp = (e)=>{
if (keyboardSpinState !== 'rest') {
setKeyboardSpinState('rest');
internalState.current.spinState = 'rest';
}
};
const commit = (e, newValue, newDisplayValue)=>{
const valueChanged = newValue !== undefined && currentValue !== newValue;
const displayValueChanged = newDisplayValue !== undefined && internalState.current.previousTextValue !== undefined && internalState.current.previousTextValue !== newDisplayValue;
let roundedValue;
if (valueChanged) {
roundedValue = precisionRound(newValue, precision);
setCurrentValue(roundedValue);
internalState.current.value = roundedValue;
} else if (displayValueChanged && !isControlled) {
const nextValue = parseFloat(newDisplayValue);
if (!isNaN(nextValue)) {
setCurrentValue(precisionRound(nextValue, precision));
internalState.current.value = precisionRound(nextValue, precision);
}
}
if (valueChanged || displayValueChanged) {
onChange === null || onChange === void 0 ? void 0 : onChange(e, {
value: roundedValue,
displayValue: newDisplayValue
});
}
setTextValue(undefined);
};
let valueToDisplay;
if (textValue !== undefined) {
valueToDisplay = textValue;
} else if (value === null || currentValue === null) {
valueToDisplay = displayValue !== null && displayValue !== void 0 ? displayValue : '';
internalState.current.value = null;
internalState.current.atBound = 'none';
} else {
const roundedValue = precisionRound(currentValue, precision);
internalState.current.value = roundedValue;
internalState.current.atBound = getBound(roundedValue, min, max);
if (isControlled) {
valueToDisplay = displayValue !== null && displayValue !== void 0 ? displayValue : String(roundedValue);
} else {
valueToDisplay = String(roundedValue);
}
}
const state = {
spinState: keyboardSpinState,
atBound: internalState.current.atBound,
components: {
root: 'span',
input: 'input',
incrementButton: 'button',
decrementButton: 'button'
},
root: slot.always(root, {
defaultProps: nativeProps.root,
elementType: 'span'
}),
input: slot.always(input, {
defaultProps: {
autoComplete: 'off',
role: 'spinbutton',
type: 'text',
...nativeProps.primary
},
elementType: 'input'
}),
incrementButton: slot.always(incrementButton, {
defaultProps: {
tabIndex: -1,
disabled: nativeProps.primary.readOnly || nativeProps.primary.disabled || internalState.current.atBound === 'max' || internalState.current.atBound === 'both',
'aria-label': 'Increment value',
type: 'button'
},
elementType: 'button'
}),
decrementButton: slot.always(decrementButton, {
defaultProps: {
tabIndex: -1,
disabled: nativeProps.primary.readOnly || nativeProps.primary.disabled || internalState.current.atBound === 'min' || internalState.current.atBound === 'both',
'aria-label': 'Decrement value',
type: 'button'
},
elementType: 'button'
})
};
state.input.value = valueToDisplay;
state.input.ref = useMergedRefs(inputRef, ref);
state.input['aria-valuemin'] = min;
state.input['aria-valuemax'] = max;
var _internalState_current_value;
state.input['aria-valuenow'] = (_internalState_current_value = internalState.current.value) !== null && _internalState_current_value !== void 0 ? _internalState_current_value : undefined;
var _state_input_ariavaluetext;
state.input['aria-valuetext'] = (_state_input_ariavaluetext = state.input['aria-valuetext']) !== null && _state_input_ariavaluetext !== void 0 ? _state_input_ariavaluetext : value !== undefined && displayValue || undefined;
state.input.onChange = mergeCallbacks(state.input.onChange, handleInputChange);
state.input.onInput = mergeCallbacks(state.input.onInput, handleInputChange);
state.input.onBlur = mergeCallbacks(state.input.onBlur, handleBlur);
state.input.onKeyDown = mergeCallbacks(state.input.onKeyDown, handleKeyDown);
state.input.onKeyUp = mergeCallbacks(state.input.onKeyUp, handleKeyUp);
state.incrementButton.onMouseDown = mergeCallbacks(handleIncrementMouseDown, state.incrementButton.onMouseDown);
state.incrementButton.onMouseUp = mergeCallbacks(state.incrementButton.onMouseUp, handleStepMouseUpOrLeave);
state.incrementButton.onMouseLeave = mergeCallbacks(state.incrementButton.onMouseLeave, handleStepMouseUpOrLeave);
state.decrementButton.onMouseDown = mergeCallbacks(handleDecrementMouseDown, state.decrementButton.onMouseDown);
state.decrementButton.onMouseUp = mergeCallbacks(state.decrementButton.onMouseUp, handleStepMouseUpOrLeave);
state.decrementButton.onMouseLeave = mergeCallbacks(state.decrementButton.onMouseLeave, handleStepMouseUpOrLeave);
return state;
};
/**
* Create the state required to render SpinButton.
*
* The returned state can be modified with hooks such as useSpinButtonStyles_unstable,
* before being passed to renderSpinButton_unstable.
*
* @param props - props from this instance of SpinButton
* @param ref - reference to root HTMLElement of SpinButton
*/ export const useSpinButton_unstable = (props, ref)=>{
var _state_incrementButton, _state_decrementButton;
// Merge props from surrounding <Field>, if any
props = useFieldControlProps_unstable(props, {
supportsLabelFor: true,
supportsRequired: true
});
const overrides = useOverrides();
var _overrides_inputDefaultAppearance;
const { appearance = (_overrides_inputDefaultAppearance = overrides.inputDefaultAppearance) !== null && _overrides_inputDefaultAppearance !== void 0 ? _overrides_inputDefaultAppearance : 'outline', size = 'medium', ...baseProps } = props;
const state = useSpinButtonBase_unstable(baseProps, ref);
var _children;
(_children = (_state_incrementButton = state.incrementButton).children) !== null && _children !== void 0 ? _children : _state_incrementButton.children = /*#__PURE__*/ React.createElement(ChevronUp16Regular, null);
var _children1;
(_children1 = (_state_decrementButton = state.decrementButton).children) !== null && _children1 !== void 0 ? _children1 : _state_decrementButton.children = /*#__PURE__*/ React.createElement(ChevronDown16Regular, null);
return {
...state,
appearance,
size
};
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,236 @@
'use client';
import { __resetStyles, __styles, mergeClasses, shorthands } from '@griffel/react';
import { tokens, typographyStyles } from '@fluentui/react-theme';
export const spinButtonClassNames = {
root: 'fui-SpinButton',
input: 'fui-SpinButton__input',
incrementButton: 'fui-SpinButton__incrementButton',
decrementButton: 'fui-SpinButton__decrementButton'
};
const spinButtonExtraClassNames = {
buttonActive: 'fui-SpinButton__button_active'
};
const fieldHeights = {
small: '24px',
medium: '32px'
};
const useRootClassName = /*#__PURE__*/__resetStyles("r109xulx", "r1h2jnch", {
r: [".r109xulx{display:inline-grid;grid-template-columns:1fr 24px;grid-template-rows:1fr 1fr;column-gap:var(--spacingHorizontalXS);row-gap:0;position:relative;isolation:isolate;vertical-align:middle;background-color:var(--colorNeutralBackground1);min-height:32px;padding:0 0 0 var(--spacingHorizontalMNudge);border-radius:var(--borderRadiusMedium);}", ".r109xulx::before{content:\"\";box-sizing:border-box;position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;z-index:10;border:1px solid var(--colorNeutralStroke1);border-bottom-color:var(--colorNeutralStrokeAccessible);border-radius:var(--borderRadiusMedium);}", ".r109xulx::after{box-sizing:border-box;content:\"\";position:absolute;right:0;bottom:0;left:0;z-index:20;height:max(2px, var(--borderRadiusMedium));border-bottom-left-radius:var(--borderRadiusMedium);border-bottom-right-radius:var(--borderRadiusMedium);border-bottom:2px solid var(--colorCompoundBrandStroke);clip-path:inset(calc(100% - 2px) 0 0 0);transform:scaleX(0);transition-property:transform;transition-duration:var(--durationUltraFast);transition-delay:var(--curveAccelerateMid);}", ".r109xulx:focus-within::after{transform:scaleX(1);transition-property:transform;transition-duration:var(--durationNormal);transition-delay:var(--curveDecelerateMid);}", ".r109xulx:focus-within:active::after{border-bottom-color:var(--colorCompoundBrandStrokePressed);}", ".r109xulx:focus-within{outline:2px solid transparent;}", ".r1h2jnch{display:inline-grid;grid-template-columns:1fr 24px;grid-template-rows:1fr 1fr;column-gap:var(--spacingHorizontalXS);row-gap:0;position:relative;isolation:isolate;vertical-align:middle;background-color:var(--colorNeutralBackground1);min-height:32px;padding:0 var(--spacingHorizontalMNudge) 0 0;border-radius:var(--borderRadiusMedium);}", ".r1h2jnch::before{content:\"\";box-sizing:border-box;position:absolute;top:0;left:0;bottom:0;right:0;pointer-events:none;z-index:10;border:1px solid var(--colorNeutralStroke1);border-bottom-color:var(--colorNeutralStrokeAccessible);border-radius:var(--borderRadiusMedium);}", ".r1h2jnch::after{box-sizing:border-box;content:\"\";position:absolute;left:0;bottom:0;right:0;z-index:20;height:max(2px, var(--borderRadiusMedium));border-bottom-right-radius:var(--borderRadiusMedium);border-bottom-left-radius:var(--borderRadiusMedium);border-bottom:2px solid var(--colorCompoundBrandStroke);clip-path:inset(calc(100% - 2px) 0 0 0);transform:scaleX(0);transition-property:transform;transition-duration:var(--durationUltraFast);transition-delay:var(--curveAccelerateMid);}", ".r1h2jnch:focus-within::after{transform:scaleX(1);transition-property:transform;transition-duration:var(--durationNormal);transition-delay:var(--curveDecelerateMid);}", ".r1h2jnch:focus-within:active::after{border-bottom-color:var(--colorCompoundBrandStrokePressed);}", ".r1h2jnch:focus-within{outline:2px solid transparent;}"],
s: ["@media screen and (prefers-reduced-motion: reduce){.r109xulx::after{transition-duration:0.01ms;transition-delay:0.01ms;}}", "@media screen and (prefers-reduced-motion: reduce){.r109xulx:focus-within::after{transition-duration:0.01ms;transition-delay:0.01ms;}}", "@media screen and (prefers-reduced-motion: reduce){.r1h2jnch::after{transition-duration:0.01ms;transition-delay:0.01ms;}}", "@media screen and (prefers-reduced-motion: reduce){.r1h2jnch:focus-within::after{transition-duration:0.01ms;transition-delay:0.01ms;}}"]
});
const useRootStyles = /*#__PURE__*/__styles({
small: {
sshi5w: "f1pha7fy",
Bahqtrf: "fk6fouc",
Be2twd7: "fy9rknc",
Bhrd7zp: "figsok6",
Bg96gwp: "fwrc4pm",
uwmqm3: ["f1f5gg8d", "f1vdfbxk"]
},
medium: {},
outline: {},
outlineInteractive: {
Bo3r8zu: "f1w2y1rc",
Hpvxnh: ["f1gofhvl", "f18htlvq"],
Bx11ytk: "ffcnd28",
B1rg0w0: ["f18htlvq", "f1gofhvl"],
Bsg1tlv: "f6lmxco",
Brjw370: ["fcoc0mf", "f15r4wkl"],
xcfy85: "f1ipdth8",
Bcc6kan: ["f15r4wkl", "fcoc0mf"]
},
underline: {
B0qfbqy: "f1o236ok",
B4f6apu: ["faeg28l", "f64aojp"],
y0oebl: "fdw6hkg",
uvfttm: ["f64aojp", "faeg28l"],
r59vdv: 0,
Budzafs: 0,
ck0cow: 0,
n07z76: 0,
Gng75u: "f1xyh2jw"
},
underlineInteractive: {
Bx11ytk: "ffcnd28",
xcfy85: "f1ipdth8",
d9w3h3: 0,
B3778ie: 0,
B4j8arr: 0,
Bl18szs: 0,
Blrzh8d: "fkp7w9h"
},
filled: {
Bcgcnre: 0,
Bqjgrrk: 0,
qa3bma: 0,
y0oebl: 0,
Biqmznv: 0,
Bm6vgfq: 0,
Bbv0w2i: 0,
uvfttm: 0,
eqrjj: 0,
Bk5zm6e: 0,
m598lv: 0,
B4f6apu: 0,
ydt019: 0,
Bq4z7u6: 0,
Bdkvgpv: 0,
B0qfbqy: 0,
kj8mxx: "f1kc0wz4"
},
"filled-darker": {
De3pzq: "f16xq7d1"
},
"filled-lighter": {
De3pzq: "fxugw4r"
},
filledInteractive: {
B05mzqr: "f1xqt08",
tb9y6h: ["fzt5lgo", "f8tv3r9"],
jcehpj: "fyhrops",
B23o0hn: ["f8tv3r9", "fzt5lgo"]
},
invalid: {
emecyz: "fl48pg9",
lz0pba: ["f1a168p3", "f1pvdymy"],
Bo1k74p: "f11knvgl",
Ba322q7: ["f1pvdymy", "f1a168p3"]
},
disabled: {
Bceei9c: "fdrzuqr",
De3pzq: "f1c21dwh",
Bq4z7u6: "f1a0lfh7",
Bk5zm6e: ["f1p2ejm6", "fmzytvz"],
Bqjgrrk: "fas2e61",
Bm6vgfq: ["fmzytvz", "f1p2ejm6"],
Bvljrlq: "f1p5b8em",
Cqojjj: ["fs6f9xf", "f11b7h5x"],
G3zxag: "f1vrn6tw",
H8270r: ["f11b7h5x", "fs6f9xf"]
}
}, {
d: [".f1pha7fy{min-height:24px;}", ".fk6fouc{font-family:var(--fontFamilyBase);}", ".fy9rknc{font-size:var(--fontSizeBase200);}", ".figsok6{font-weight:var(--fontWeightRegular);}", ".fwrc4pm{line-height:var(--lineHeightBase200);}", ".f1f5gg8d{padding-left:var(--spacingHorizontalS);}", ".f1vdfbxk{padding-right:var(--spacingHorizontalS);}", ".f1o236ok::before{border-top-width:0;}", ".faeg28l::before{border-right-width:0;}", ".f64aojp::before{border-left-width:0;}", ".fdw6hkg::before{border-bottom-width:1px;}", [".f1xyh2jw::before{border-radius:var(--borderRadiusNone);}", {
p: -1
}], [".fkp7w9h::after{border-radius:var(--borderRadiusNone);}", {
p: -1
}], [".f1kc0wz4::before{border:1px solid var(--colorTransparentStroke);}", {
p: -2
}], ".f16xq7d1{background-color:var(--colorNeutralBackground3);}", ".fxugw4r{background-color:var(--colorNeutralBackground1);}", ".fl48pg9:not(:focus-within)::before,.fl48pg9:hover:not(:focus-within)::before{border-top-color:var(--colorPaletteRedBorder2);}", ".f1a168p3:not(:focus-within)::before,.f1a168p3:hover:not(:focus-within)::before{border-right-color:var(--colorPaletteRedBorder2);}", ".f1pvdymy:not(:focus-within)::before,.f1pvdymy:hover:not(:focus-within)::before{border-left-color:var(--colorPaletteRedBorder2);}", ".f11knvgl:not(:focus-within)::before,.f11knvgl:hover:not(:focus-within)::before{border-bottom-color:var(--colorPaletteRedBorder2);}", ".fdrzuqr{cursor:not-allowed;}", ".f1c21dwh{background-color:var(--colorTransparentBackground);}", ".f1a0lfh7::before{border-top-color:var(--colorNeutralStrokeDisabled);}", ".f1p2ejm6::before{border-right-color:var(--colorNeutralStrokeDisabled);}", ".fmzytvz::before{border-left-color:var(--colorNeutralStrokeDisabled);}", ".fas2e61::before{border-bottom-color:var(--colorNeutralStrokeDisabled);}"],
h: [".f1w2y1rc:hover::before{border-top-color:var(--colorNeutralStroke1Hover);}", ".f1gofhvl:hover::before{border-right-color:var(--colorNeutralStroke1Hover);}", ".f18htlvq:hover::before{border-left-color:var(--colorNeutralStroke1Hover);}", ".ffcnd28:hover::before{border-bottom-color:var(--colorNeutralStrokeAccessibleHover);}", ".f1xqt08:hover::before,.f1xqt08:focus-within::before{border-top-color:var(--colorTransparentStrokeInteractive);}", ".fzt5lgo:hover::before,.fzt5lgo:focus-within::before{border-right-color:var(--colorTransparentStrokeInteractive);}", ".f8tv3r9:hover::before,.f8tv3r9:focus-within::before{border-left-color:var(--colorTransparentStrokeInteractive);}", ".fyhrops:hover::before,.fyhrops:focus-within::before{border-bottom-color:var(--colorTransparentStrokeInteractive);}"],
a: [".f6lmxco:active::before,.f6lmxco:focus-within::before{border-top-color:var(--colorNeutralStroke1Pressed);}", ".fcoc0mf:active::before,.fcoc0mf:focus-within::before{border-right-color:var(--colorNeutralStroke1Pressed);}", ".f15r4wkl:active::before,.f15r4wkl:focus-within::before{border-left-color:var(--colorNeutralStroke1Pressed);}", ".f1ipdth8:active::before,.f1ipdth8:focus-within::before{border-bottom-color:var(--colorNeutralStrokeAccessiblePressed);}"],
m: [["@media (forced-colors: active){.f1p5b8em::before{border-top-color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f11b7h5x::before{border-left-color:GrayText;}.fs6f9xf::before{border-right-color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1vrn6tw::before{border-bottom-color:GrayText;}}", {
m: "(forced-colors: active)"
}]]
});
const useInputClassName = /*#__PURE__*/__resetStyles("r1ljrqje", null, [".r1ljrqje{grid-column-start:1;grid-column-end:2;grid-row-start:1;grid-row-end:3;outline-style:none;border:0;padding:0;color:var(--colorNeutralForeground1);background-color:transparent;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;width:100%;}", ".r1ljrqje::-webkit-input-placeholder{color:var(--colorNeutralForeground4);opacity:1;}", ".r1ljrqje::-moz-placeholder{color:var(--colorNeutralForeground4);opacity:1;}", ".r1ljrqje::placeholder{color:var(--colorNeutralForeground4);opacity:1;}"]);
const useInputStyles = /*#__PURE__*/__styles({
disabled: {
sj55zd: "f1s2aq7o",
Bceei9c: "fdrzuqr",
De3pzq: "f1c21dwh",
yvdlaj: "fahhnxm"
}
}, {
d: [".f1s2aq7o{color:var(--colorNeutralForegroundDisabled);}", ".fdrzuqr{cursor:not-allowed;}", ".f1c21dwh{background-color:var(--colorTransparentBackground);}", ".fahhnxm::-webkit-input-placeholder{color:var(--colorNeutralForegroundDisabled);}", ".fahhnxm::-moz-placeholder{color:var(--colorNeutralForegroundDisabled);}"]
});
const useBaseButtonClassName = /*#__PURE__*/__resetStyles("r1g4chgs", null, [".r1g4chgs{display:inline-flex;width:24px;align-items:center;justify-content:center;border:0;position:absolute;outline-style:none;height:16px;background-color:transparent;color:var(--colorNeutralForeground3);grid-column-start:2;border-radius:0;padding:0 5px 0 5px;}", ".r1g4chgs:active{outline-style:none;}", ".r1g4chgs:enabled:hover{cursor:pointer;color:var(--colorNeutralForeground3Hover);background-color:var(--colorSubtleBackgroundHover);}", ".r1g4chgs:enabled:active{color:var(--colorNeutralForeground3Pressed);background-color:var(--colorSubtleBackgroundPressed);}", ".r1g4chgs:enabled.fui-SpinButton__button_active{color:var(--colorNeutralForeground3Pressed);background-color:var(--colorSubtleBackgroundPressed);}", ".r1g4chgs:disabled{cursor:not-allowed;color:var(--colorNeutralForegroundDisabled);}"]);
const useButtonStyles = /*#__PURE__*/__styles({
increment: {
Ijaq50: "f16hsg94",
B7oj6ja: ["f1jar5jt", "fyu767a"],
z8tnut: "f10ra9hq",
Byoj8tv: "f1brlhvm"
},
decrement: {
Ijaq50: "faunodf",
Bbmb7ep: ["f1aa9q02", "f16jpd5f"],
z8tnut: "f1sl3k7w",
Byoj8tv: "f1y2xyjm"
},
incrementButtonSmall: {
Byoj8tv: 0,
uwmqm3: 0,
z189sj: 0,
z8tnut: 0,
B0ocmuz: ["f4lv8q1", "fm3uwd2"],
Bqenvij: "fvblgha"
},
decrementButtonSmall: {
Byoj8tv: 0,
uwmqm3: 0,
z189sj: 0,
z8tnut: 0,
B0ocmuz: ["f1q86st8", "frkrfqj"],
Bqenvij: "fvblgha"
},
outline: {},
underline: {
De3pzq: "f3rmtva",
sj55zd: "f11d4kpn",
r4wkhp: "f1no7wuu",
B95qlz1: "f1bifk9c",
p743kt: "fp1zg4s",
B7xitij: "fo6hitd",
B6siaa6: "f1wiab75",
Ba9qmo4: "fj9zm5z",
Dyrjrp: "f1cqwcg4"
},
"filled-darker": {
De3pzq: "f3rmtva",
sj55zd: "f11d4kpn",
r4wkhp: "f1no7wuu",
B95qlz1: "fwwxidx",
p743kt: "fp1zg4s",
B7xitij: "f14i52sd",
B6siaa6: "f1wiab75",
Ba9qmo4: "fwry2ka",
Dyrjrp: "f1cqwcg4"
},
"filled-lighter": {
De3pzq: "f3rmtva",
sj55zd: "f11d4kpn",
r4wkhp: "f1no7wuu",
B95qlz1: "f1yywxnv",
drw0cw: "fzaa11h",
idzz8t: "f4fpmm9",
Dyrjrp: "f1cqwcg4"
}
}, {
d: [".f16hsg94{grid-row-start:1;}", ".f1jar5jt{border-top-right-radius:var(--borderRadiusMedium);}", ".fyu767a{border-top-left-radius:var(--borderRadiusMedium);}", ".f10ra9hq{padding-top:4px;}", ".f1brlhvm{padding-bottom:1px;}", ".faunodf{grid-row-start:2;}", ".f1aa9q02{border-bottom-right-radius:var(--borderRadiusMedium);}", ".f16jpd5f{border-bottom-left-radius:var(--borderRadiusMedium);}", ".f1sl3k7w{padding-top:1px;}", ".f1y2xyjm{padding-bottom:4px;}", [".f4lv8q1{padding:3px 6px 0px 4px;}", {
p: -1
}], [".fm3uwd2{padding:3px 4px 0px 6px;}", {
p: -1
}], ".fvblgha{height:12px;}", [".f1q86st8{padding:0px 6px 3px 4px;}", {
p: -1
}], [".frkrfqj{padding:0px 4px 3px 6px;}", {
p: -1
}], ".f3rmtva{background-color:transparent;}", ".f11d4kpn{color:var(--colorNeutralForeground3);}", ".f1no7wuu:enabled:hover{color:var(--colorNeutralForeground3Hover);}", ".f1bifk9c:enabled:hover{background-color:var(--colorSubtleBackgroundHover);}", ".fp1zg4s:enabled:active{color:var(--colorNeutralForeground3Pressed);}", ".fo6hitd:enabled:active{background-color:var(--colorSubtleBackgroundPressed);}", ".f1wiab75:enabled.fui-SpinButton__button_active{color:var(--colorNeutralForeground3Pressed);}", ".fj9zm5z:enabled.fui-SpinButton__button_active{background-color:var(--colorSubtleBackgroundPressed);}", ".f1cqwcg4:disabled{color:var(--colorNeutralForegroundDisabled);}", ".fwwxidx:enabled:hover{background-color:var(--colorNeutralBackground3Hover);}", ".f14i52sd:enabled:active{background-color:var(--colorNeutralBackground3Pressed);}", ".fwry2ka:enabled.fui-SpinButton__button_active{background-color:var(--colorNeutralBackground3Pressed);}", ".f1yywxnv:enabled:hover{background-color:var(--colorNeutralBackground1Hover);}", ".fzaa11h:enabled:active,.fzaa11h:enabled.fui-SpinButton__button_active{color:var(--colorNeutralForeground3Pressed);}", ".f4fpmm9:enabled:active,.f4fpmm9:enabled.fui-SpinButton__button_active{background-color:var(--colorNeutralBackground1Pressed);}"]
});
/**
* Apply styling to the SpinButton slots based on the state
*/
export const useSpinButtonStyles_unstable = state => {
'use no memo';
const {
appearance,
spinState,
size
} = state;
const disabled = state.input.disabled;
const invalid = `${state.input['aria-invalid']}` === 'true';
const filled = appearance.startsWith('filled');
const rootStyles = useRootStyles();
const buttonStyles = useButtonStyles();
const inputStyles = useInputStyles();
state.root.className = mergeClasses(spinButtonClassNames.root, useRootClassName(), rootStyles[size], rootStyles[appearance], filled && rootStyles.filled, !disabled && appearance === 'outline' && rootStyles.outlineInteractive, !disabled && appearance === 'underline' && rootStyles.underlineInteractive, !disabled && filled && rootStyles.filledInteractive, !disabled && invalid && rootStyles.invalid, disabled && rootStyles.disabled, state.root.className);
state.incrementButton.className = mergeClasses(spinButtonClassNames.incrementButton, spinState === 'up' && `${spinButtonExtraClassNames.buttonActive}`, useBaseButtonClassName(), buttonStyles.increment, buttonStyles[appearance], size === 'small' && buttonStyles.incrementButtonSmall, state.incrementButton.className);
state.decrementButton.className = mergeClasses(spinButtonClassNames.decrementButton, spinState === 'down' && `${spinButtonExtraClassNames.buttonActive}`, useBaseButtonClassName(), buttonStyles.decrement, buttonStyles[appearance], size === 'small' && buttonStyles.decrementButtonSmall, state.decrementButton.className);
state.input.className = mergeClasses(spinButtonClassNames.input, useInputClassName(), disabled && inputStyles.disabled, state.input.className);
return state;
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,360 @@
'use client';
import { makeResetStyles, makeStyles, mergeClasses, shorthands } from '@griffel/react';
import { tokens, typographyStyles } from '@fluentui/react-theme';
export const spinButtonClassNames = {
root: 'fui-SpinButton',
input: 'fui-SpinButton__input',
incrementButton: 'fui-SpinButton__incrementButton',
decrementButton: 'fui-SpinButton__decrementButton'
};
const spinButtonExtraClassNames = {
buttonActive: 'fui-SpinButton__button_active'
};
const fieldHeights = {
small: '24px',
medium: '32px'
};
const useRootClassName = makeResetStyles({
display: 'inline-grid',
gridTemplateColumns: `1fr 24px`,
gridTemplateRows: '1fr 1fr',
columnGap: tokens.spacingHorizontalXS,
rowGap: 0,
position: 'relative',
isolation: 'isolate',
verticalAlign: 'middle',
backgroundColor: tokens.colorNeutralBackground1,
minHeight: fieldHeights.medium,
padding: `0 0 0 ${tokens.spacingHorizontalMNudge}`,
borderRadius: tokens.borderRadiusMedium,
// Apply border styles on the ::before pseudo element.
// We cannot use ::after since that is used for selection.
// Using the pseudo element allows us to place the border
// above content in the component which ensures the buttons
// line up visually with the border as expected. Without this
// there is a bit of a gap which can become very noticeable
// at high zoom or when OS zoom levels are not divisible by 2
// (e.g., 150% on Windows in Firefox)
// This is most noticeable on the "outline" appearance which is
// also the default so it feels worth the extra ceremony to get right.
'::before': {
content: '""',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
pointerEvents: 'none',
zIndex: 10,
border: `1px solid ${tokens.colorNeutralStroke1}`,
borderBottomColor: tokens.colorNeutralStrokeAccessible,
borderRadius: tokens.borderRadiusMedium
},
'::after': {
boxSizing: 'border-box',
content: '""',
position: 'absolute',
right: 0,
bottom: 0,
left: 0,
zIndex: 20,
// Maintaining the correct corner radius:
// Use the whole border-radius as the height and only put radii on the bottom corners.
// (Otherwise the radius would be automatically reduced to fit available space.)
// max() ensures the focus border still shows up even if someone sets tokens.borderRadiusMedium to 0.
height: `max(2px, ${tokens.borderRadiusMedium})`,
borderBottomLeftRadius: tokens.borderRadiusMedium,
borderBottomRightRadius: tokens.borderRadiusMedium,
// Flat 2px border:
// By default borderBottom will cause little "horns" on the ends. The clipPath trims them off.
// (This could be done without trimming using `background: linear-gradient(...)`, but using
// borderBottom makes it easier for people to override the color if needed.)
borderBottom: `2px solid ${tokens.colorCompoundBrandStroke}`,
clipPath: 'inset(calc(100% - 2px) 0 0 0)',
// Animation for focus OUT
transform: 'scaleX(0)',
transitionProperty: 'transform',
transitionDuration: tokens.durationUltraFast,
transitionDelay: tokens.curveAccelerateMid,
'@media screen and (prefers-reduced-motion: reduce)': {
transitionDuration: '0.01ms',
transitionDelay: '0.01ms'
}
},
':focus-within::after': {
// Animation for focus IN
transform: 'scaleX(1)',
transitionProperty: 'transform',
transitionDuration: tokens.durationNormal,
transitionDelay: tokens.curveDecelerateMid,
'@media screen and (prefers-reduced-motion: reduce)': {
transitionDuration: '0.01ms',
transitionDelay: '0.01ms'
}
},
':focus-within:active::after': {
// This is if the user clicks the field again while it's already focused
borderBottomColor: tokens.colorCompoundBrandStrokePressed
},
':focus-within': {
outline: '2px solid transparent'
}
});
const useRootStyles = makeStyles({
small: {
minHeight: fieldHeights.small,
...typographyStyles.caption1,
paddingLeft: tokens.spacingHorizontalS
},
medium: {
},
outline: {
},
outlineInteractive: {
':hover::before': {
...shorthands.borderColor(tokens.colorNeutralStroke1Hover),
borderBottomColor: tokens.colorNeutralStrokeAccessibleHover
},
// DO NOT add a space between the selectors! It changes the behavior of make-styles.
':active,:focus-within': {
'::before': {
...shorthands.borderColor(tokens.colorNeutralStroke1Pressed),
borderBottomColor: tokens.colorNeutralStrokeAccessiblePressed
}
}
},
underline: {
'::before': {
...shorthands.borderWidth(0, 0, '1px', 0),
borderRadius: tokens.borderRadiusNone
}
},
underlineInteractive: {
':hover::before': {
borderBottomColor: tokens.colorNeutralStrokeAccessibleHover
},
// DO NOT add a space between the selectors! It changes the behavior of make-styles.
':active,:focus-within': {
'::before': {
borderBottomColor: tokens.colorNeutralStrokeAccessiblePressed
}
},
'::after': {
borderRadius: tokens.borderRadiusNone
}
},
filled: {
'::before': {
border: `1px solid ${tokens.colorTransparentStroke}`
}
},
'filled-darker': {
backgroundColor: tokens.colorNeutralBackground3
},
'filled-lighter': {
backgroundColor: tokens.colorNeutralBackground1
},
filledInteractive: {
// DO NOT add a space between the selectors! It changes the behavior of make-styles.
':hover,:focus-within': {
'::before': {
// also handles pressed border color (:active)
...shorthands.borderColor(tokens.colorTransparentStrokeInteractive)
}
}
},
invalid: {
':not(:focus-within),:hover:not(:focus-within)': {
'::before': {
...shorthands.borderColor(tokens.colorPaletteRedBorder2)
}
}
},
disabled: {
cursor: 'not-allowed',
backgroundColor: tokens.colorTransparentBackground,
'::before': {
...shorthands.borderColor(tokens.colorNeutralStrokeDisabled),
'@media (forced-colors: active)': {
...shorthands.borderColor('GrayText')
}
}
}
});
const useInputClassName = makeResetStyles({
gridColumnStart: '1',
gridColumnEnd: '2',
gridRowStart: '1',
gridRowEnd: '3',
outlineStyle: 'none',
border: '0',
padding: '0',
color: tokens.colorNeutralForeground1,
// Use literal "transparent" (not from the theme) to always let the color from the root show through
backgroundColor: 'transparent',
fontFamily: 'inherit',
fontSize: 'inherit',
fontWeight: 'inherit',
lineHeight: 'inherit',
width: '100%',
'::placeholder': {
color: tokens.colorNeutralForeground4,
opacity: 1
}
});
const useInputStyles = makeStyles({
disabled: {
color: tokens.colorNeutralForegroundDisabled,
cursor: 'not-allowed',
backgroundColor: tokens.colorTransparentBackground,
'::placeholder': {
color: tokens.colorNeutralForegroundDisabled
}
}
});
const useBaseButtonClassName = makeResetStyles({
display: 'inline-flex',
width: '24px',
alignItems: 'center',
justifyContent: 'center',
border: '0',
position: 'absolute',
outlineStyle: 'none',
height: '16px',
// Use literal "transparent" (not from the theme) to always let the color from the root show through
backgroundColor: 'transparent',
color: tokens.colorNeutralForeground3,
// common button layout
gridColumnStart: '2',
borderRadius: '0',
padding: '0 5px 0 5px',
':active': {
outlineStyle: 'none'
},
':enabled': {
':hover': {
cursor: 'pointer',
color: tokens.colorNeutralForeground3Hover,
backgroundColor: tokens.colorSubtleBackgroundHover
},
':active': {
color: tokens.colorNeutralForeground3Pressed,
backgroundColor: tokens.colorSubtleBackgroundPressed
},
[`&.${spinButtonExtraClassNames.buttonActive}`]: {
color: tokens.colorNeutralForeground3Pressed,
backgroundColor: tokens.colorSubtleBackgroundPressed
}
},
':disabled': {
cursor: 'not-allowed',
color: tokens.colorNeutralForegroundDisabled
}
});
const useButtonStyles = makeStyles({
increment: {
gridRowStart: '1',
borderTopRightRadius: tokens.borderRadiusMedium,
paddingTop: '4px',
paddingBottom: '1px'
},
decrement: {
gridRowStart: '2',
borderBottomRightRadius: tokens.borderRadiusMedium,
paddingTop: '1px',
paddingBottom: '4px'
},
// Padding values numbers don't align with design specs
// but visually the padding aligns.
// The icons are set in a 16x16px square but the artwork is inset from that
// so these padding values are computed by hand.
// Additionally the design uses fractional values so these are
// rounded to the nearest integer.
incrementButtonSmall: {
padding: '3px 6px 0px 4px',
height: '12px'
},
decrementButtonSmall: {
padding: '0px 6px 3px 4px',
height: '12px'
},
outline: {
},
underline: {
backgroundColor: 'transparent',
color: tokens.colorNeutralForeground3,
':enabled': {
':hover': {
color: tokens.colorNeutralForeground3Hover,
backgroundColor: tokens.colorSubtleBackgroundHover
},
':active': {
color: tokens.colorNeutralForeground3Pressed,
backgroundColor: tokens.colorSubtleBackgroundPressed
},
[`&.${spinButtonExtraClassNames.buttonActive}`]: {
color: tokens.colorNeutralForeground3Pressed,
backgroundColor: tokens.colorSubtleBackgroundPressed
}
},
':disabled': {
color: tokens.colorNeutralForegroundDisabled
}
},
'filled-darker': {
backgroundColor: 'transparent',
color: tokens.colorNeutralForeground3,
':enabled': {
':hover': {
color: tokens.colorNeutralForeground3Hover,
backgroundColor: tokens.colorNeutralBackground3Hover
},
':active': {
color: tokens.colorNeutralForeground3Pressed,
backgroundColor: tokens.colorNeutralBackground3Pressed
},
[`&.${spinButtonExtraClassNames.buttonActive}`]: {
color: tokens.colorNeutralForeground3Pressed,
backgroundColor: tokens.colorNeutralBackground3Pressed
}
},
':disabled': {
color: tokens.colorNeutralForegroundDisabled
}
},
'filled-lighter': {
backgroundColor: 'transparent',
color: tokens.colorNeutralForeground3,
':enabled': {
':hover': {
color: tokens.colorNeutralForeground3Hover,
backgroundColor: tokens.colorNeutralBackground1Hover
},
[`:active,&.${spinButtonExtraClassNames.buttonActive}`]: {
color: tokens.colorNeutralForeground3Pressed,
backgroundColor: tokens.colorNeutralBackground1Pressed
}
},
':disabled': {
color: tokens.colorNeutralForegroundDisabled
}
}
});
/**
* Apply styling to the SpinButton slots based on the state
*/ export const useSpinButtonStyles_unstable = (state)=>{
'use no memo';
const { appearance, spinState, size } = state;
const disabled = state.input.disabled;
const invalid = `${state.input['aria-invalid']}` === 'true';
const filled = appearance.startsWith('filled');
const rootStyles = useRootStyles();
const buttonStyles = useButtonStyles();
const inputStyles = useInputStyles();
state.root.className = mergeClasses(spinButtonClassNames.root, useRootClassName(), rootStyles[size], rootStyles[appearance], filled && rootStyles.filled, !disabled && appearance === 'outline' && rootStyles.outlineInteractive, !disabled && appearance === 'underline' && rootStyles.underlineInteractive, !disabled && filled && rootStyles.filledInteractive, !disabled && invalid && rootStyles.invalid, disabled && rootStyles.disabled, state.root.className);
state.incrementButton.className = mergeClasses(spinButtonClassNames.incrementButton, spinState === 'up' && `${spinButtonExtraClassNames.buttonActive}`, useBaseButtonClassName(), buttonStyles.increment, buttonStyles[appearance], size === 'small' && buttonStyles.incrementButtonSmall, state.incrementButton.className);
state.decrementButton.className = mergeClasses(spinButtonClassNames.decrementButton, spinState === 'down' && `${spinButtonExtraClassNames.buttonActive}`, useBaseButtonClassName(), buttonStyles.decrement, buttonStyles[appearance], size === 'small' && buttonStyles.decrementButtonSmall, state.decrementButton.className);
state.input.className = mergeClasses(spinButtonClassNames.input, useInputClassName(), disabled && inputStyles.disabled, state.input.className);
return state;
};

File diff suppressed because one or more lines are too long

1
node_modules/@fluentui/react-spinbutton/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1 @@
export { SpinButton, renderSpinButton_unstable, spinButtonClassNames, useSpinButtonStyles_unstable, useSpinButtonBase_unstable, useSpinButton_unstable } from './SpinButton';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n SpinButton,\n renderSpinButton_unstable,\n spinButtonClassNames,\n useSpinButtonStyles_unstable,\n useSpinButtonBase_unstable,\n useSpinButton_unstable,\n} from './SpinButton';\nexport type {\n SpinButtonBaseProps,\n SpinButtonBaseState,\n SpinButtonOnChangeData,\n SpinButtonChangeEvent,\n SpinButtonProps,\n SpinButtonSlots,\n SpinButtonState,\n SpinButtonSpinState,\n SpinButtonBounds,\n} from './SpinButton';\n"],"names":["SpinButton","renderSpinButton_unstable","spinButtonClassNames","useSpinButtonStyles_unstable","useSpinButtonBase_unstable","useSpinButton_unstable"],"mappings":"AAAA,SACEA,UAAU,EACVC,yBAAyB,EACzBC,oBAAoB,EACpBC,4BAA4B,EAC5BC,0BAA0B,EAC1BC,sBAAsB,QACjB,eAAe"}

View File

@@ -0,0 +1,23 @@
export const clamp = (value, min, max)=>{
let nextValue = value;
if (min !== undefined) {
if (max !== undefined && min > max) {
const error = new Error();
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.error([
`"min" value "${min}" is greater than "max" value "${max}".`,
'"min" must be less than or equal to "max".',
`Returning value "${value}".`,
error.stack
].join());
}
return value;
}
nextValue = Math.max(min, nextValue);
}
if (max !== undefined) {
nextValue = Math.min(max, nextValue);
}
return nextValue;
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/clamp.ts"],"sourcesContent":["export const clamp = (value: number, min?: number, max?: number): number => {\n let nextValue = value;\n if (min !== undefined) {\n if (max !== undefined && min > max) {\n const error = new Error();\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(\n [\n `\"min\" value \"${min}\" is greater than \"max\" value \"${max}\".`,\n '\"min\" must be less than or equal to \"max\".',\n `Returning value \"${value}\".`,\n error.stack,\n ].join(),\n );\n }\n return value;\n }\n\n nextValue = Math.max(min, nextValue);\n }\n\n if (max !== undefined) {\n nextValue = Math.min(max, nextValue);\n }\n\n return nextValue;\n};\n"],"names":["clamp","value","min","max","nextValue","undefined","error","Error","process","env","NODE_ENV","console","stack","join","Math"],"mappings":"AAAA,OAAO,MAAMA,QAAQ,CAACC,OAAeC,KAAcC;IACjD,IAAIC,YAAYH;IAChB,IAAIC,QAAQG,WAAW;QACrB,IAAIF,QAAQE,aAAaH,MAAMC,KAAK;YAClC,MAAMG,QAAQ,IAAIC;YAClB,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzC,sCAAsC;gBACtCC,QAAQL,KAAK,CACX;oBACE,CAAC,aAAa,EAAEJ,IAAI,+BAA+B,EAAEC,IAAI,EAAE,CAAC;oBAC5D;oBACA,CAAC,iBAAiB,EAAEF,MAAM,EAAE,CAAC;oBAC7BK,MAAMM,KAAK;iBACZ,CAACC,IAAI;YAEV;YACA,OAAOZ;QACT;QAEAG,YAAYU,KAAKX,GAAG,CAACD,KAAKE;IAC5B;IAEA,IAAID,QAAQE,WAAW;QACrBD,YAAYU,KAAKZ,GAAG,CAACC,KAAKC;IAC5B;IAEA,OAAOA;AACT,EAAE"}

View File

@@ -0,0 +1,11 @@
export const getBound = (value, min, max)=>{
if (min !== undefined && value === min) {
if (max === min) {
return 'both';
}
return 'min';
} else if (max !== undefined && value === max) {
return 'max';
}
return 'none';
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/getBound.ts"],"sourcesContent":["import type { SpinButtonBounds } from '../SpinButton';\n\nexport const getBound = (value: number, min?: number, max?: number): SpinButtonBounds => {\n if (min !== undefined && value === min) {\n if (max === min) {\n return 'both';\n }\n return 'min';\n } else if (max !== undefined && value === max) {\n return 'max';\n }\n\n return 'none';\n};\n"],"names":["getBound","value","min","max","undefined"],"mappings":"AAEA,OAAO,MAAMA,WAAW,CAACC,OAAeC,KAAcC;IACpD,IAAID,QAAQE,aAAaH,UAAUC,KAAK;QACtC,IAAIC,QAAQD,KAAK;YACf,OAAO;QACT;QACA,OAAO;IACT,OAAO,IAAIC,QAAQC,aAAaH,UAAUE,KAAK;QAC7C,OAAO;IACT;IAEA,OAAO;AACT,EAAE"}

View File

@@ -0,0 +1,3 @@
export { clamp } from './clamp';
export { getBound } from './getBound';
export { calculatePrecision, precisionRound } from './precision';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/index.ts"],"sourcesContent":["export { clamp } from './clamp';\nexport { getBound } from './getBound';\nexport { calculatePrecision, precisionRound } from './precision';\n"],"names":["clamp","getBound","calculatePrecision","precisionRound"],"mappings":"AAAA,SAASA,KAAK,QAAQ,UAAU;AAChC,SAASC,QAAQ,QAAQ,aAAa;AACtC,SAASC,kBAAkB,EAAEC,cAAc,QAAQ,cAAc"}

View File

@@ -0,0 +1,32 @@
/**
* Calculates a number's precision based on the number of trailing
* zeros if the number does not have a decimal indicated by a negative
* precision. Otherwise, it calculates the number of digits after
* the decimal point indicated by a positive precision.
* @param value - the value to determine the precision of
*/ export function calculatePrecision(value) {
/**
* Group 1:
* [1-9]([0]+$) matches trailing zeros
* Group 2:
* \.([0-9]*) matches all digits after a decimal point.
*/ const groups = /[1-9]([0]+$)|\.([0-9]*)/.exec(String(value));
if (!groups) {
return 0;
}
if (groups[1]) {
return -groups[1].length;
}
if (groups[2]) {
return groups[2].length;
}
return 0;
}
/**
* Rounds a number to a certain level of precision. Accepts negative precision.
* @param value - The value that is being rounded.
* @param precision - The number of decimal places to round the number to
*/ export function precisionRound(value, precision, base = 10) {
const exp = base ** precision;
return Math.round(value * exp) / exp;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/precision.ts"],"sourcesContent":["/**\n * Calculates a number's precision based on the number of trailing\n * zeros if the number does not have a decimal indicated by a negative\n * precision. Otherwise, it calculates the number of digits after\n * the decimal point indicated by a positive precision.\n * @param value - the value to determine the precision of\n */\nexport function calculatePrecision(value: number | string): number {\n /**\n * Group 1:\n * [1-9]([0]+$) matches trailing zeros\n * Group 2:\n * \\.([0-9]*) matches all digits after a decimal point.\n */\n const groups = /[1-9]([0]+$)|\\.([0-9]*)/.exec(String(value));\n if (!groups) {\n return 0;\n }\n if (groups[1]) {\n return -groups[1].length;\n }\n if (groups[2]) {\n return groups[2].length;\n }\n return 0;\n}\n\n/**\n * Rounds a number to a certain level of precision. Accepts negative precision.\n * @param value - The value that is being rounded.\n * @param precision - The number of decimal places to round the number to\n */\nexport function precisionRound(value: number, precision: number, base: number = 10): number {\n const exp = base ** precision;\n return Math.round(value * exp) / exp;\n}\n"],"names":["calculatePrecision","value","groups","exec","String","length","precisionRound","precision","base","exp","Math","round"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,SAASA,mBAAmBC,KAAsB;IACvD;;;;;GAKC,GACD,MAAMC,SAAS,0BAA0BC,IAAI,CAACC,OAAOH;IACrD,IAAI,CAACC,QAAQ;QACX,OAAO;IACT;IACA,IAAIA,MAAM,CAAC,EAAE,EAAE;QACb,OAAO,CAACA,MAAM,CAAC,EAAE,CAACG,MAAM;IAC1B;IACA,IAAIH,MAAM,CAAC,EAAE,EAAE;QACb,OAAOA,MAAM,CAAC,EAAE,CAACG,MAAM;IACzB;IACA,OAAO;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASC,eAAeL,KAAa,EAAEM,SAAiB,EAAEC,OAAe,EAAE;IAChF,MAAMC,MAAMD,QAAQD;IACpB,OAAOG,KAAKC,KAAK,CAACV,QAAQQ,OAAOA;AACnC"}

52
node_modules/@fluentui/react-spinbutton/package.json generated vendored Normal file
View File

@@ -0,0 +1,52 @@
{
"name": "@fluentui/react-spinbutton",
"version": "9.6.1",
"description": "Fluent UI React SpinButton component.",
"main": "lib-commonjs/index.js",
"module": "lib/index.js",
"typings": "./dist/index.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/microsoft/fluentui"
},
"license": "MIT",
"dependencies": {
"@fluentui/keyboard-keys": "^9.0.8",
"@fluentui/react-field": "^9.5.0",
"@fluentui/react-icons": "^2.0.245",
"@fluentui/react-jsx-runtime": "^9.4.1",
"@fluentui/react-shared-contexts": "^9.26.2",
"@fluentui/react-theme": "^9.2.1",
"@fluentui/react-utilities": "^9.26.2",
"@griffel/react": "^1.5.32",
"@swc/helpers": "^0.5.1"
},
"peerDependencies": {
"@types/react": ">=16.14.0 <20.0.0",
"@types/react-dom": ">=16.9.0 <20.0.0",
"react": ">=16.14.0 <20.0.0",
"react-dom": ">=16.14.0 <20.0.0"
},
"beachball": {
"disallowedChangeTypes": [
"major",
"prerelease"
]
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"node": "./lib-commonjs/index.js",
"import": "./lib/index.js",
"require": "./lib-commonjs/index.js"
},
"./package.json": "./package.json"
},
"files": [
"*.md",
"dist/*.d.ts",
"lib",
"lib-commonjs"
]
}