@onerjs/shared-ui-components 8.36.1 → 8.36.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,8 +9,8 @@ import { Body1 } from "@fluentui/react-components";
9
9
  */
10
10
  export const StringifiedPropertyLine = (props) => {
11
11
  StringifiedPropertyLine.displayName = "StringifiedPropertyLine";
12
- const value = props.precision !== undefined ? props.value.toFixed(props.precision) : props.value.toLocaleString();
12
+ const value = props.precision !== undefined ? props.value?.toFixed(props.precision) : props.value?.toLocaleString();
13
13
  const withUnits = props.units ? `${value} ${props.units}` : value;
14
- return (_jsx(PropertyLine, { ...props, children: _jsx(Body1, { title: props.title, children: withUnits }) }));
14
+ return (_jsx(PropertyLine, { ...props, children: _jsx(Body1, { title: props.title, children: withUnits ?? "" }) }));
15
15
  };
16
16
  //# sourceMappingURL=stringifiedPropertyLine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stringifiedPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/stringifiedPropertyLine.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAQnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAoD,CAAC,KAAK,EAAE,EAAE;IAC9F,uBAAuB,CAAC,WAAW,GAAG,yBAAyB,CAAC;IAChE,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;IAClH,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,OAAO,CACH,KAAC,YAAY,OAAK,KAAK,YACnB,KAAC,KAAK,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YAAG,SAAS,GAAS,GACnC,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { ImmutablePrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport { Body1 } from \"@fluentui/react-components\";\r\n\r\ntype StringifiedPropertyLineProps = PropertyLineProps<number> &\r\n ImmutablePrimitiveProps<number> & {\r\n precision?: number;\r\n units?: string;\r\n };\r\n\r\n/**\r\n * Expects a numerical value and converts it toFixed(if precision is supplied) or toLocaleString\r\n * Can pass optional units to be appending to the end of the string\r\n * @param props\r\n * @returns\r\n */\r\nexport const StringifiedPropertyLine: FunctionComponent<StringifiedPropertyLineProps> = (props) => {\r\n StringifiedPropertyLine.displayName = \"StringifiedPropertyLine\";\r\n const value = props.precision !== undefined ? props.value.toFixed(props.precision) : props.value.toLocaleString();\r\n const withUnits = props.units ? `${value} ${props.units}` : value;\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1 title={props.title}>{withUnits}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
1
+ {"version":3,"file":"stringifiedPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/stringifiedPropertyLine.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAQnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAoD,CAAC,KAAK,EAAE,EAAE;IAC9F,uBAAuB,CAAC,WAAW,GAAG,yBAAyB,CAAC;IAChE,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC;IACpH,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,OAAO,CACH,KAAC,YAAY,OAAK,KAAK,YACnB,KAAC,KAAK,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YAAG,SAAS,IAAI,EAAE,GAAS,GACzC,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { ImmutablePrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport { Body1 } from \"@fluentui/react-components\";\r\n\r\ntype StringifiedPropertyLineProps = PropertyLineProps<number> &\r\n ImmutablePrimitiveProps<number> & {\r\n precision?: number;\r\n units?: string;\r\n };\r\n\r\n/**\r\n * Expects a numerical value and converts it toFixed(if precision is supplied) or toLocaleString\r\n * Can pass optional units to be appending to the end of the string\r\n * @param props\r\n * @returns\r\n */\r\nexport const StringifiedPropertyLine: FunctionComponent<StringifiedPropertyLineProps> = (props) => {\r\n StringifiedPropertyLine.displayName = \"StringifiedPropertyLine\";\r\n const value = props.precision !== undefined ? props.value?.toFixed(props.precision) : props.value?.toLocaleString();\r\n const withUnits = props.units ? `${value} ${props.units}` : value;\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1 title={props.title}>{withUnits ?? \"\"}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
@@ -9,6 +9,6 @@ import { PropertyLine } from "./propertyLine.js";
9
9
  export const TextPropertyLine = (props) => {
10
10
  TextPropertyLine.displayName = "TextPropertyLine";
11
11
  const { value, title } = props;
12
- return (_jsx(PropertyLine, { ...props, children: _jsx(Body1, { title: title, children: value }) }));
12
+ return (_jsx(PropertyLine, { ...props, children: _jsx(Body1, { title: title, children: value ?? "" }) }));
13
13
  };
14
14
  //# sourceMappingURL=textPropertyLine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"textPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/textPropertyLine.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAmF,CAAC,KAAK,EAAE,EAAE;IACtH,gBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC;IAClD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC/B,OAAO,CACH,KAAC,YAAY,OAAK,KAAK,YACnB,KAAC,KAAK,IAAC,KAAK,EAAE,KAAK,YAAG,KAAK,GAAS,GACzB,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { Body1 } from \"@fluentui/react-components\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { ImmutablePrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\nimport type { FunctionComponent } from \"react\";\r\n\r\n/**\r\n * Wraps text in a property line\r\n * @param props - PropertyLineProps and TextProps\r\n * @returns property-line wrapped text\r\n */\r\nexport const TextPropertyLine: FunctionComponent<PropertyLineProps<string> & ImmutablePrimitiveProps<string>> = (props) => {\r\n TextPropertyLine.displayName = \"TextPropertyLine\";\r\n const { value, title } = props;\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1 title={title}>{value}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
1
+ {"version":3,"file":"textPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/textPropertyLine.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAmF,CAAC,KAAK,EAAE,EAAE;IACtH,gBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC;IAClD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC/B,OAAO,CACH,KAAC,YAAY,OAAK,KAAK,YACnB,KAAC,KAAK,IAAC,KAAK,EAAE,KAAK,YAAG,KAAK,IAAI,EAAE,GAAS,GAC/B,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { Body1 } from \"@fluentui/react-components\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { ImmutablePrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\nimport type { FunctionComponent } from \"react\";\r\n\r\n/**\r\n * Wraps text in a property line\r\n * @param props - PropertyLineProps and TextProps\r\n * @returns property-line wrapped text\r\n */\r\nexport const TextPropertyLine: FunctionComponent<PropertyLineProps<string> & ImmutablePrimitiveProps<string>> = (props) => {\r\n TextPropertyLine.displayName = \"TextPropertyLine\";\r\n const { value, title } = props;\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1 title={title}>{value ?? \"\"}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
@@ -4,12 +4,12 @@ import type { BasePrimitiveProps } from "./primitive.js";
4
4
  export type ButtonProps = BasePrimitiveProps & {
5
5
  onClick?: (e?: MouseEvent<HTMLButtonElement>) => unknown | Promise<unknown>;
6
6
  icon?: FluentIcon;
7
- appearance?: "subtle" | "transparent" | "primary";
7
+ appearance?: "subtle" | "transparent" | "primary" | "secondary";
8
8
  label?: string;
9
9
  };
10
10
  export declare const Button: import("react").ForwardRefExoticComponent<BasePrimitiveProps & {
11
11
  onClick?: (e?: MouseEvent<HTMLButtonElement>) => unknown | Promise<unknown>;
12
12
  icon?: FluentIcon;
13
- appearance?: "subtle" | "transparent" | "primary";
13
+ appearance?: "subtle" | "transparent" | "primary" | "secondary";
14
14
  label?: string;
15
15
  } & import("react").RefAttributes<HTMLButtonElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAEzF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,eAAe,GAAG,UAAU,CAAC;IAC/B,SAAS,EAAE;QACP,QAAQ,EAAE,QAAQ,CAAC,IAAI;KAC1B;IACD,UAAU,EAAE;QACR,QAAQ,EAAE,QAAQ,CAAC,IAAI;KAC1B;CACJ,CAAC,CAAC;AASH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC5E,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,gEAAgE;IAChE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,GAAG,KAAK,CAAC;IAElF,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,WAAW,CAC7B,KAAK,EAAE,CAAgC,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YAC5B,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,IAAI,CAAC;gBACD,MAAM,MAAM,CAAC;YACjB,CAAC;oBAAS,CAAC;gBACP,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACL,CAAC;IACL,CAAC,EACD,CAAC,OAAO,CAAC,CACZ,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAE5E,OAAO,CACH,KAAC,YAAY,IACT,GAAG,EAAE,GAAG,EACR,YAAY,EAAC,OAAO,KAChB,WAAW,EACf,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,IAAI,EAAC,YAAY,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,KAAC,IAAI,IAAC,SAAS,EAAE,SAAS,GAAI,EAC5F,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,QAAQ,IAAI,aAAa,YAElC,KAAK,IAAI,KAAK,CAAC,KAAK,GACV,CAClB,CAAC;AACN,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC","sourcesContent":["import { Button as FluentButton, makeStyles, Spinner } from \"@fluentui/react-components\";\r\nimport type { MouseEvent } from \"react\";\r\nimport { forwardRef, useCallback, useContext, useState } from \"react\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\nimport type { BasePrimitiveProps } from \"./primitive\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\nimport { TokenMap } from \"./utils\";\r\n\r\nconst useButtonStyles = makeStyles({\r\n smallIcon: {\r\n fontSize: TokenMap.px16,\r\n },\r\n mediumIcon: {\r\n fontSize: TokenMap.px20,\r\n },\r\n});\r\n\r\nexport type ButtonProps = BasePrimitiveProps & {\r\n onClick?: (e?: MouseEvent<HTMLButtonElement>) => unknown | Promise<unknown>;\r\n icon?: FluentIcon;\r\n appearance?: \"subtle\" | \"transparent\" | \"primary\";\r\n label?: string;\r\n};\r\n\r\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const classes = useButtonStyles();\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const { icon: Icon, label, onClick, disabled, className, ...buttonProps } = props;\r\n\r\n const [isOnClickBusy, setIsOnClickBusy] = useState(false);\r\n const handleOnClick = useCallback(\r\n async (e: MouseEvent<HTMLButtonElement>) => {\r\n const result = onClick?.(e);\r\n if (result instanceof Promise) {\r\n setIsOnClickBusy(true);\r\n try {\r\n await result;\r\n } finally {\r\n setIsOnClickBusy(false);\r\n }\r\n }\r\n },\r\n [onClick]\r\n );\r\n\r\n const iconClass = size === \"small\" ? classes.smallIcon : classes.mediumIcon;\r\n\r\n return (\r\n <FluentButton\r\n ref={ref}\r\n iconPosition=\"after\"\r\n {...buttonProps}\r\n className={className}\r\n size={size}\r\n icon={isOnClickBusy ? <Spinner size=\"extra-tiny\" /> : Icon && <Icon className={iconClass} />}\r\n onClick={handleOnClick}\r\n disabled={disabled || isOnClickBusy}\r\n >\r\n {label && props.label}\r\n </FluentButton>\r\n );\r\n});\r\n\r\nButton.displayName = \"Button\";\r\n"]}
1
+ {"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAEzF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,eAAe,GAAG,UAAU,CAAC;IAC/B,SAAS,EAAE;QACP,QAAQ,EAAE,QAAQ,CAAC,IAAI;KAC1B;IACD,UAAU,EAAE;QACR,QAAQ,EAAE,QAAQ,CAAC,IAAI;KAC1B;CACJ,CAAC,CAAC;AASH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC5E,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,gEAAgE;IAChE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,GAAG,KAAK,CAAC;IAElF,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,WAAW,CAC7B,KAAK,EAAE,CAAgC,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YAC5B,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,IAAI,CAAC;gBACD,MAAM,MAAM,CAAC;YACjB,CAAC;oBAAS,CAAC;gBACP,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACL,CAAC;IACL,CAAC,EACD,CAAC,OAAO,CAAC,CACZ,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAE5E,OAAO,CACH,KAAC,YAAY,IACT,GAAG,EAAE,GAAG,EACR,YAAY,EAAC,OAAO,KAChB,WAAW,EACf,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,IAAI,EAAC,YAAY,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,KAAC,IAAI,IAAC,SAAS,EAAE,SAAS,GAAI,EAC5F,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,QAAQ,IAAI,aAAa,YAElC,KAAK,IAAI,KAAK,CAAC,KAAK,GACV,CAClB,CAAC;AACN,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC","sourcesContent":["import { Button as FluentButton, makeStyles, Spinner } from \"@fluentui/react-components\";\r\nimport type { MouseEvent } from \"react\";\r\nimport { forwardRef, useCallback, useContext, useState } from \"react\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\nimport type { BasePrimitiveProps } from \"./primitive\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\nimport { TokenMap } from \"./utils\";\r\n\r\nconst useButtonStyles = makeStyles({\r\n smallIcon: {\r\n fontSize: TokenMap.px16,\r\n },\r\n mediumIcon: {\r\n fontSize: TokenMap.px20,\r\n },\r\n});\r\n\r\nexport type ButtonProps = BasePrimitiveProps & {\r\n onClick?: (e?: MouseEvent<HTMLButtonElement>) => unknown | Promise<unknown>;\r\n icon?: FluentIcon;\r\n appearance?: \"subtle\" | \"transparent\" | \"primary\" | \"secondary\";\r\n label?: string;\r\n};\r\n\r\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const classes = useButtonStyles();\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const { icon: Icon, label, onClick, disabled, className, ...buttonProps } = props;\r\n\r\n const [isOnClickBusy, setIsOnClickBusy] = useState(false);\r\n const handleOnClick = useCallback(\r\n async (e: MouseEvent<HTMLButtonElement>) => {\r\n const result = onClick?.(e);\r\n if (result instanceof Promise) {\r\n setIsOnClickBusy(true);\r\n try {\r\n await result;\r\n } finally {\r\n setIsOnClickBusy(false);\r\n }\r\n }\r\n },\r\n [onClick]\r\n );\r\n\r\n const iconClass = size === \"small\" ? classes.smallIcon : classes.mediumIcon;\r\n\r\n return (\r\n <FluentButton\r\n ref={ref}\r\n iconPosition=\"after\"\r\n {...buttonProps}\r\n className={className}\r\n size={size}\r\n icon={isOnClickBusy ? <Spinner size=\"extra-tiny\" /> : Icon && <Icon className={iconClass} />}\r\n onClick={handleOnClick}\r\n disabled={disabled || isOnClickBusy}\r\n >\r\n {label && props.label}\r\n </FluentButton>\r\n );\r\n});\r\n\r\nButton.displayName = \"Button\";\r\n"]}
@@ -36,7 +36,7 @@ export function EntitySelector(props) {
36
36
  return getEntities()
37
37
  .filter((e) => e.uniqueId !== undefined && (!filter || filter(e)))
38
38
  .map((entity) => ({
39
- label: getName(entity).toString(),
39
+ label: getName(entity)?.toString() || "",
40
40
  value: entity.uniqueId.toString(),
41
41
  }))
42
42
  .sort((a, b) => a.label.localeCompare(b.label));
@@ -54,9 +54,9 @@ export function EntitySelector(props) {
54
54
  return (_jsxs("div", { className: classes.linkDiv, children: [_jsx(Tooltip, { content: getName(value), relationship: "label", children: _jsx(Link, { className: classes.link, value: getName(value), onLink: () => onLink(value) }) }), onChange &&
55
55
  (defaultValue !== undefined ? (
56
56
  // If the defaultValue is specified, then allow resetting to the default
57
- _jsx(Button, { icon: LinkDismissRegular, onClick: () => onChange(defaultValue) })) : (
57
+ _jsx(Tooltip, { content: "Unlink", relationship: "label", children: _jsx(Button, { icon: LinkDismissRegular, onClick: () => onChange(defaultValue) }) })) : (
58
58
  // Otherwise, just allow editing to a new value
59
- _jsx(Button, { icon: LinkEditRegular, onClick: () => setIsEditing(true) })))] }));
59
+ _jsx(Tooltip, { content: "Edit Link", relationship: "label", children: _jsx(Button, { icon: LinkEditRegular, onClick: () => setIsEditing(true) }) })))] }));
60
60
  }
61
61
  else {
62
62
  // Otherwise, show the ComboBox for selection
@@ -1 +1 @@
1
- {"version":3,"file":"entitySelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/entitySelector.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"core/types\";\r\nimport type { ImmutablePrimitiveProps, PrimitiveProps } from \"./primitive\";\r\n\r\nimport { useMemo, useState } from \"react\";\r\nimport { LinkDismissRegular, LinkEditRegular } from \"@fluentui/react-icons\";\r\nimport { ComboBox } from \"./comboBox\";\r\nimport { Link } from \"./link\";\r\nimport { Button } from \"./button\";\r\nimport { makeStyles, tokens, Tooltip } from \"@fluentui/react-components\";\r\n\r\ntype Entity = { uniqueId: number };\r\n\r\n/**\r\n * Props for the EntitySelector component\r\n */\r\nexport type EntitySelectorProps<T extends Entity> = (PrimitiveProps<Nullable<T>> | ImmutablePrimitiveProps<Nullable<T>>) & {\r\n /**\r\n * Function to get the list of entities to choose from\r\n */\r\n getEntities: () => T[];\r\n /**\r\n * Function to get the display name from an entity\r\n */\r\n getName: (entity: T) => string;\r\n /**\r\n * Optional filter function to filter which entities are shown\r\n */\r\n filter?: (entity: T) => boolean;\r\n /**\r\n * Callback when the entity link is clicked\r\n */\r\n onLink: (entity: T) => void;\r\n /**\r\n * Optional default value that enables clearing the current linked entity\r\n */\r\n defaultValue?: T;\r\n};\r\n\r\nconst useStyles = makeStyles({\r\n linkDiv: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n gap: tokens.spacingHorizontalS,\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n },\r\n link: {\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n});\r\n\r\n/**\r\n * A generic primitive component with a ComboBox for selecting from a list of entities.\r\n * Supports entities with duplicate names by using uniqueId for identity.\r\n * @param props ChooseEntityProps\r\n * @returns EntitySelector component\r\n */\r\nexport function EntitySelector<T extends Entity>(props: EntitySelectorProps<T>): JSX.Element {\r\n const { value, onLink, getEntities, getName, filter, defaultValue } = props;\r\n\r\n const onChange = (props as PrimitiveProps<Nullable<T>>).onChange as PrimitiveProps<Nullable<T>>[\"onChange\"] | undefined;\r\n\r\n const classes = useStyles();\r\n\r\n // Build options with uniqueId as key\r\n const options = useMemo(() => {\r\n return getEntities()\r\n .filter((e) => e.uniqueId !== undefined && (!filter || filter(e)))\r\n .map((entity) => ({\r\n label: getName(entity).toString(),\r\n value: entity.uniqueId.toString(),\r\n }))\r\n .sort((a, b) => a.label.localeCompare(b.label));\r\n }, [getEntities, getName, filter]);\r\n\r\n const [isEditing, setIsEditing] = useState(false);\r\n\r\n const handleEntitySelect = (key: string) => {\r\n const entity = getEntities().find((e) => e.uniqueId.toString() === key);\r\n onChange?.(entity ?? null);\r\n setIsEditing(false);\r\n };\r\n\r\n // Get current entity key for display\r\n const currentKey = value ? value.uniqueId.toString() : \"\";\r\n\r\n if (value && !isEditing) {\r\n // If there is a value and we are not editing, show the link view\r\n return (\r\n <div className={classes.linkDiv}>\r\n <Tooltip content={getName(value)} relationship=\"label\">\r\n <Link className={classes.link} value={getName(value)} onLink={() => onLink(value)} />\r\n </Tooltip>\r\n {/* Only allow changing the linked entity if an onChange handler is provided */}\r\n {onChange &&\r\n (defaultValue !== undefined ? (\r\n // If the defaultValue is specified, then allow resetting to the default\r\n <Button icon={LinkDismissRegular} onClick={() => onChange(defaultValue)} />\r\n ) : (\r\n // Otherwise, just allow editing to a new value\r\n <Button icon={LinkEditRegular} onClick={() => setIsEditing(true)} />\r\n ))}\r\n </div>\r\n );\r\n } else {\r\n // Otherwise, show the ComboBox for selection\r\n return <ComboBox label=\"\" options={options} value={currentKey} onChange={handleEntitySelect} />;\r\n }\r\n}\r\nEntitySelector.displayName = \"EntitySelector\";\r\n"]}
1
+ {"version":3,"file":"entitySelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/entitySelector.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"core/types\";\r\nimport type { ImmutablePrimitiveProps, PrimitiveProps } from \"./primitive\";\r\n\r\nimport { useMemo, useState } from \"react\";\r\nimport { LinkDismissRegular, LinkEditRegular } from \"@fluentui/react-icons\";\r\nimport { ComboBox } from \"./comboBox\";\r\nimport { Link } from \"./link\";\r\nimport { Button } from \"./button\";\r\nimport { makeStyles, tokens, Tooltip } from \"@fluentui/react-components\";\r\n\r\ntype Entity = { uniqueId: number };\r\n\r\n/**\r\n * Props for the EntitySelector component\r\n */\r\nexport type EntitySelectorProps<T extends Entity> = (PrimitiveProps<Nullable<T>> | ImmutablePrimitiveProps<Nullable<T>>) & {\r\n /**\r\n * Function to get the list of entities to choose from\r\n */\r\n getEntities: () => T[];\r\n /**\r\n * Function to get the display name from an entity\r\n */\r\n getName: (entity: T) => string;\r\n /**\r\n * Optional filter function to filter which entities are shown\r\n */\r\n filter?: (entity: T) => boolean;\r\n /**\r\n * Callback when the entity link is clicked\r\n */\r\n onLink: (entity: T) => void;\r\n /**\r\n * Optional default value that enables clearing the current linked entity\r\n */\r\n defaultValue?: T;\r\n};\r\n\r\nconst useStyles = makeStyles({\r\n linkDiv: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n gap: tokens.spacingHorizontalS,\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n },\r\n link: {\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n});\r\n\r\n/**\r\n * A generic primitive component with a ComboBox for selecting from a list of entities.\r\n * Supports entities with duplicate names by using uniqueId for identity.\r\n * @param props ChooseEntityProps\r\n * @returns EntitySelector component\r\n */\r\nexport function EntitySelector<T extends Entity>(props: EntitySelectorProps<T>): JSX.Element {\r\n const { value, onLink, getEntities, getName, filter, defaultValue } = props;\r\n\r\n const onChange = (props as PrimitiveProps<Nullable<T>>).onChange as PrimitiveProps<Nullable<T>>[\"onChange\"] | undefined;\r\n\r\n const classes = useStyles();\r\n\r\n // Build options with uniqueId as key\r\n const options = useMemo(() => {\r\n return getEntities()\r\n .filter((e) => e.uniqueId !== undefined && (!filter || filter(e)))\r\n .map((entity) => ({\r\n label: getName(entity)?.toString() || \"\",\r\n value: entity.uniqueId.toString(),\r\n }))\r\n .sort((a, b) => a.label.localeCompare(b.label));\r\n }, [getEntities, getName, filter]);\r\n\r\n const [isEditing, setIsEditing] = useState(false);\r\n\r\n const handleEntitySelect = (key: string) => {\r\n const entity = getEntities().find((e) => e.uniqueId.toString() === key);\r\n onChange?.(entity ?? null);\r\n setIsEditing(false);\r\n };\r\n\r\n // Get current entity key for display\r\n const currentKey = value ? value.uniqueId.toString() : \"\";\r\n\r\n if (value && !isEditing) {\r\n // If there is a value and we are not editing, show the link view\r\n return (\r\n <div className={classes.linkDiv}>\r\n <Tooltip content={getName(value)} relationship=\"label\">\r\n <Link className={classes.link} value={getName(value)} onLink={() => onLink(value)} />\r\n </Tooltip>\r\n {/* Only allow changing the linked entity if an onChange handler is provided */}\r\n {onChange &&\r\n (defaultValue !== undefined ? (\r\n // If the defaultValue is specified, then allow resetting to the default\r\n <Tooltip content=\"Unlink\" relationship=\"label\">\r\n <Button icon={LinkDismissRegular} onClick={() => onChange(defaultValue)} />\r\n </Tooltip>\r\n ) : (\r\n // Otherwise, just allow editing to a new value\r\n <Tooltip content=\"Edit Link\" relationship=\"label\">\r\n <Button icon={LinkEditRegular} onClick={() => setIsEditing(true)} />\r\n </Tooltip>\r\n ))}\r\n </div>\r\n );\r\n } else {\r\n // Otherwise, show the ComboBox for selection\r\n return <ComboBox label=\"\" options={options} value={currentKey} onChange={handleEntitySelect} />;\r\n }\r\n}\r\nEntitySelector.displayName = \"EntitySelector\";\r\n"]}
@@ -13,8 +13,8 @@ export type ListItem<T> = {
13
13
  type ListProps<T> = {
14
14
  items: ListItem<T>[];
15
15
  renderItem: (item: ListItem<T>, index: number) => ReactNode;
16
- onDelete: (item: ListItem<T>, index: number) => void;
17
- onAdd: (item?: ListItem<T>) => void;
16
+ onDelete?: (item: ListItem<T>, index: number) => void;
17
+ onAdd?: (item?: ListItem<T>) => void;
18
18
  addButtonLabel?: string;
19
19
  };
20
20
  /**
@@ -38,6 +38,6 @@ export function List(props) {
38
38
  const { items, renderItem, onDelete, onAdd, addButtonLabel = "Add new item" } = props;
39
39
  const classes = useListStyles();
40
40
  const sortedItems = useMemo(() => [...items].sort((a, b) => a.sortBy - b.sortBy), [items]);
41
- return (_jsxs("div", { children: [_jsx(ButtonLine, { label: addButtonLabel, icon: AddRegular, onClick: () => props.onAdd() }), _jsx("div", { className: classes.list, children: sortedItems.map((item, index) => (_jsxs("div", { className: classes.item, children: [_jsxs(Body1Strong, { className: classes.itemId, children: ["#", index] }), _jsx("div", { className: classes.itemContent, children: renderItem(item, items.indexOf(sortedItems[index])) }), _jsxs("div", { className: classes.iconContainer, children: [_jsx(CopyRegular, { onClick: () => onAdd(item) }), _jsx(DeleteRegular, { onClick: () => onDelete(item, items.indexOf(sortedItems[index])) })] })] }, item.id))) })] }));
41
+ return (_jsxs("div", { children: [onAdd && _jsx(ButtonLine, { label: addButtonLabel, icon: AddRegular, onClick: () => onAdd() }), _jsx("div", { className: classes.list, children: sortedItems.map((item, index) => (_jsxs("div", { className: classes.item, children: [_jsxs(Body1Strong, { className: classes.itemId, children: ["#", index] }), _jsx("div", { className: classes.itemContent, children: renderItem(item, items.indexOf(sortedItems[index])) }), (onAdd || onDelete) && (_jsxs("div", { className: classes.iconContainer, children: [onAdd && _jsx(CopyRegular, { onClick: () => onAdd(item) }), onDelete && _jsx(DeleteRegular, { onClick: () => onDelete(item, items.indexOf(sortedItems[index])) })] }))] }, item.id))) })] }));
42
42
  }
43
43
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/list.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,aAAa,GAAG,UAAU,CAAC;IAC7B,IAAI,EAAE;QACF,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK,EAAE,6BAA6B;QACnD,UAAU,EAAE,QAAQ,EAAE,0BAA0B;QAChD,GAAG,EAAE,MAAM,CAAC,kBAAkB,EAAE,6BAA6B;QAC7D,YAAY,EAAE,GAAG,MAAM,CAAC,eAAe,UAAU,MAAM,CAAC,mBAAmB,EAAE;KAChF;IACD,MAAM,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC,kBAAkB;KACnC;IACD,WAAW,EAAE;QACT,IAAI,EAAE,CAAC,EAAE,0BAA0B;QACnC,QAAQ,EAAE,CAAC,EAAE,qCAAqC;KACrD;IACD,aAAa,EAAE;QACX,OAAO,EAAE,MAAM;QACf,GAAG,EAAE,MAAM,CAAC,mBAAmB,EAAE,0BAA0B;QAC3D,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,CAAC,EAAE,oBAAoB;KACtC;IACD,IAAI,EAAE;QACF,OAAO,EAAE,MAAM,CAAC,gBAAgB;KACnC;CACJ,CAAC,CAAC;AAsBH;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAI,KAAmB;IACvC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc,EAAE,GAAG,KAAK,CAAC;IACtF,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAEhC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAE3F,OAAO,CACH,0BACI,KAAC,UAAU,IAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,GAAI,EAErF,cAAK,SAAS,EAAE,OAAO,CAAC,IAAI,YACvB,WAAW,CAAC,GAAG,CAAC,CAAC,IAAiB,EAAE,KAAa,EAAE,EAAE,CAAC,CACnD,eAAmB,SAAS,EAAE,OAAO,CAAC,IAAI,aACtC,MAAC,WAAW,IAAC,SAAS,EAAE,OAAO,CAAC,MAAM,kBAAI,KAAK,IAAe,EAC9D,cAAK,SAAS,EAAE,OAAO,CAAC,WAAW,YAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,GAAO,EAChG,eAAK,SAAS,EAAE,OAAO,CAAC,aAAa,aACjC,KAAC,WAAW,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAI,EAC3C,KAAC,aAAa,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,GAAI,IACjF,KANA,IAAI,CAAC,EAAE,CAOX,CACT,CAAC,GACA,IACJ,CACT,CAAC;AACN,CAAC","sourcesContent":["import type { ReactElement, ReactNode } from \"react\";\r\n\r\nimport { Body1Strong, makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport { AddRegular, CopyRegular, DeleteRegular } from \"@fluentui/react-icons\";\r\nimport { useMemo } from \"react\";\r\n\r\nimport { ButtonLine } from \"../hoc/buttonLine\";\r\n\r\nconst useListStyles = makeStyles({\r\n item: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"row\", // Arrange items horizontally\r\n alignItems: \"center\", // Center items vertically\r\n gap: tokens.spacingHorizontalS, // Add space between elements\r\n borderBottom: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralStroke1}`,\r\n },\r\n itemId: {\r\n width: tokens.spacingHorizontalM,\r\n },\r\n itemContent: {\r\n flex: 1, // Take up remaining space\r\n minWidth: 0, // Prevent flex item from overflowing\r\n },\r\n iconContainer: {\r\n display: \"flex\",\r\n gap: tokens.spacingHorizontalXS, // Small gap between icons\r\n alignItems: \"center\",\r\n flexShrink: 0, // Prevent shrinking\r\n },\r\n list: {\r\n padding: tokens.spacingVerticalS,\r\n },\r\n});\r\n\r\n/**\r\n * Represents an item in a list\r\n */\r\nexport type ListItem<T> = {\r\n /** Unique identifier for the item */\r\n id: number;\r\n /** The data associated with the item */\r\n data: T;\r\n /** Value to use for sorting the list */\r\n sortBy: number;\r\n};\r\n\r\ntype ListProps<T> = {\r\n items: ListItem<T>[];\r\n renderItem: (item: ListItem<T>, index: number) => ReactNode;\r\n onDelete: (item: ListItem<T>, index: number) => void;\r\n onAdd: (item?: ListItem<T>) => void;\r\n addButtonLabel?: string;\r\n};\r\n\r\n/**\r\n * For cases where you may want to add / remove items from a list via a trash can button / copy button, this HOC can be used\r\n * @returns A React component that renders a list of items with add/delete functionality\r\n * @param props - The properties for the List component\r\n */\r\nexport function List<T>(props: ListProps<T>): ReactElement {\r\n const { items, renderItem, onDelete, onAdd, addButtonLabel = \"Add new item\" } = props;\r\n const classes = useListStyles();\r\n\r\n const sortedItems = useMemo(() => [...items].sort((a, b) => a.sortBy - b.sortBy), [items]);\r\n\r\n return (\r\n <div>\r\n <ButtonLine label={addButtonLabel} icon={AddRegular} onClick={() => props.onAdd()} />\r\n\r\n <div className={classes.list}>\r\n {sortedItems.map((item: ListItem<T>, index: number) => (\r\n <div key={item.id} className={classes.item}>\r\n <Body1Strong className={classes.itemId}>#{index}</Body1Strong>\r\n <div className={classes.itemContent}>{renderItem(item, items.indexOf(sortedItems[index]))}</div>\r\n <div className={classes.iconContainer}>\r\n <CopyRegular onClick={() => onAdd(item)} />\r\n <DeleteRegular onClick={() => onDelete(item, items.indexOf(sortedItems[index]))} />\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"]}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/list.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,aAAa,GAAG,UAAU,CAAC;IAC7B,IAAI,EAAE;QACF,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK,EAAE,6BAA6B;QACnD,UAAU,EAAE,QAAQ,EAAE,0BAA0B;QAChD,GAAG,EAAE,MAAM,CAAC,kBAAkB,EAAE,6BAA6B;QAC7D,YAAY,EAAE,GAAG,MAAM,CAAC,eAAe,UAAU,MAAM,CAAC,mBAAmB,EAAE;KAChF;IACD,MAAM,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC,kBAAkB;KACnC;IACD,WAAW,EAAE;QACT,IAAI,EAAE,CAAC,EAAE,0BAA0B;QACnC,QAAQ,EAAE,CAAC,EAAE,qCAAqC;KACrD;IACD,aAAa,EAAE;QACX,OAAO,EAAE,MAAM;QACf,GAAG,EAAE,MAAM,CAAC,mBAAmB,EAAE,0BAA0B;QAC3D,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,CAAC,EAAE,oBAAoB;KACtC;IACD,IAAI,EAAE;QACF,OAAO,EAAE,MAAM,CAAC,gBAAgB;KACnC;CACJ,CAAC,CAAC;AAsBH;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAI,KAAmB;IACvC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc,EAAE,GAAG,KAAK,CAAC;IACtF,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAEhC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAE3F,OAAO,CACH,0BACK,KAAK,IAAI,KAAC,UAAU,IAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,GAAI,EAEzF,cAAK,SAAS,EAAE,OAAO,CAAC,IAAI,YACvB,WAAW,CAAC,GAAG,CAAC,CAAC,IAAiB,EAAE,KAAa,EAAE,EAAE,CAAC,CACnD,eAAmB,SAAS,EAAE,OAAO,CAAC,IAAI,aACtC,MAAC,WAAW,IAAC,SAAS,EAAE,OAAO,CAAC,MAAM,kBAAI,KAAK,IAAe,EAC9D,cAAK,SAAS,EAAE,OAAO,CAAC,WAAW,YAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,GAAO,EAC/F,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CACpB,eAAK,SAAS,EAAE,OAAO,CAAC,aAAa,aAChC,KAAK,IAAI,KAAC,WAAW,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAI,EACpD,QAAQ,IAAI,KAAC,aAAa,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,GAAI,IAC9F,CACT,KARK,IAAI,CAAC,EAAE,CASX,CACT,CAAC,GACA,IACJ,CACT,CAAC;AACN,CAAC","sourcesContent":["import type { ReactElement, ReactNode } from \"react\";\r\n\r\nimport { Body1Strong, makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport { AddRegular, CopyRegular, DeleteRegular } from \"@fluentui/react-icons\";\r\nimport { useMemo } from \"react\";\r\n\r\nimport { ButtonLine } from \"../hoc/buttonLine\";\r\n\r\nconst useListStyles = makeStyles({\r\n item: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"row\", // Arrange items horizontally\r\n alignItems: \"center\", // Center items vertically\r\n gap: tokens.spacingHorizontalS, // Add space between elements\r\n borderBottom: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralStroke1}`,\r\n },\r\n itemId: {\r\n width: tokens.spacingHorizontalM,\r\n },\r\n itemContent: {\r\n flex: 1, // Take up remaining space\r\n minWidth: 0, // Prevent flex item from overflowing\r\n },\r\n iconContainer: {\r\n display: \"flex\",\r\n gap: tokens.spacingHorizontalXS, // Small gap between icons\r\n alignItems: \"center\",\r\n flexShrink: 0, // Prevent shrinking\r\n },\r\n list: {\r\n padding: tokens.spacingVerticalS,\r\n },\r\n});\r\n\r\n/**\r\n * Represents an item in a list\r\n */\r\nexport type ListItem<T> = {\r\n /** Unique identifier for the item */\r\n id: number;\r\n /** The data associated with the item */\r\n data: T;\r\n /** Value to use for sorting the list */\r\n sortBy: number;\r\n};\r\n\r\ntype ListProps<T> = {\r\n items: ListItem<T>[];\r\n renderItem: (item: ListItem<T>, index: number) => ReactNode;\r\n onDelete?: (item: ListItem<T>, index: number) => void;\r\n onAdd?: (item?: ListItem<T>) => void;\r\n addButtonLabel?: string;\r\n};\r\n\r\n/**\r\n * For cases where you may want to add / remove items from a list via a trash can button / copy button, this HOC can be used\r\n * @returns A React component that renders a list of items with add/delete functionality\r\n * @param props - The properties for the List component\r\n */\r\nexport function List<T>(props: ListProps<T>): ReactElement {\r\n const { items, renderItem, onDelete, onAdd, addButtonLabel = \"Add new item\" } = props;\r\n const classes = useListStyles();\r\n\r\n const sortedItems = useMemo(() => [...items].sort((a, b) => a.sortBy - b.sortBy), [items]);\r\n\r\n return (\r\n <div>\r\n {onAdd && <ButtonLine label={addButtonLabel} icon={AddRegular} onClick={() => onAdd()} />}\r\n\r\n <div className={classes.list}>\r\n {sortedItems.map((item: ListItem<T>, index: number) => (\r\n <div key={item.id} className={classes.item}>\r\n <Body1Strong className={classes.itemId}>#{index}</Body1Strong>\r\n <div className={classes.itemContent}>{renderItem(item, items.indexOf(sortedItems[index]))}</div>\r\n {(onAdd || onDelete) && (\r\n <div className={classes.iconContainer}>\r\n {onAdd && <CopyRegular onClick={() => onAdd(item)} />}\r\n {onDelete && <DeleteRegular onClick={() => onDelete(item, items.indexOf(sortedItems[index]))} />}\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"]}
@@ -1,4 +1,5 @@
1
1
  import type { PropsWithChildren, ReactElement } from "react";
2
+ import type { PositioningShorthand } from "@fluentui/react-components";
2
3
  import type { FluentIcon } from "@fluentui/react-icons";
3
4
  type PopoverWithIconProps = {
4
5
  icon: FluentIcon;
@@ -8,6 +9,16 @@ type PopoverWithTriggerProps = {
8
9
  icon?: never;
9
10
  trigger: ReactElement;
10
11
  };
11
- type PopoverProps = PopoverWithIconProps | PopoverWithTriggerProps;
12
+ type PopoverBaseProps = {
13
+ /** Controlled open state */
14
+ open?: boolean;
15
+ /** Callback when open state changes */
16
+ onOpenChange?: (open: boolean) => void;
17
+ /** Positioning of the popover */
18
+ positioning?: PositioningShorthand;
19
+ /** Custom class for the surface */
20
+ surfaceClassName?: string;
21
+ };
22
+ type PopoverProps = PopoverBaseProps & (PopoverWithIconProps | PopoverWithTriggerProps);
12
23
  export declare const Popover: import("react").ForwardRefExoticComponent<PropsWithChildren<PopoverProps> & import("react").RefAttributes<HTMLButtonElement>>;
13
24
  export {};
@@ -15,13 +15,22 @@ const useStyles = makeStyles({
15
15
  },
16
16
  });
17
17
  export const Popover = forwardRef((props, ref) => {
18
- const { children } = props;
19
- const [popoverOpen, setPopoverOpen] = useState(false);
18
+ const { children, open: controlledOpen, onOpenChange, positioning, surfaceClassName } = props;
19
+ const [internalOpen, setInternalOpen] = useState(false);
20
20
  const classes = useStyles();
21
- return (_jsxs(FluentPopover, { open: popoverOpen, onOpenChange: (_, data) => setPopoverOpen(data.open), positioning: {
21
+ const isControlled = controlledOpen !== undefined;
22
+ const popoverOpen = isControlled ? controlledOpen : internalOpen;
23
+ const handleOpenChange = (_, data) => {
24
+ if (!isControlled) {
25
+ setInternalOpen(data.open);
26
+ }
27
+ onOpenChange?.(data.open);
28
+ };
29
+ return (_jsxs(FluentPopover, { open: popoverOpen, onOpenChange: handleOpenChange, positioning: positioning ?? {
22
30
  align: "start",
23
31
  overflowBoundary: document.body,
24
32
  autoSize: true,
25
- }, trapFocus: true, children: [_jsx(PopoverTrigger, { disableButtonEnhancement: true, children: props.trigger ?? _jsx(Button, { ref: ref, icon: props.icon, onClick: () => setPopoverOpen(true) }) }), _jsx(PopoverSurface, { className: classes.surface, children: _jsx("div", { className: classes.content, children: children }) })] }));
33
+ }, children: [_jsx(PopoverTrigger, { disableButtonEnhancement: true, children: props.trigger ?? _jsx(Button, { ref: ref, icon: props.icon, onClick: () => handleOpenChange(null, { open: true }) }) }), _jsx(PopoverSurface, { className: surfaceClassName ?? classes.surface, children: _jsx("div", { className: classes.content, children: children }) })] }));
26
34
  });
35
+ Popover.displayName = "Popover";
27
36
  //# sourceMappingURL=popover.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/popover.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAE1H,OAAO,EAAE,MAAM,EAAE,MAAM,+CAA+C,CAAC;AAEvE,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,OAAO,EAAE;QACL,QAAQ,EAAE,OAAO;KACpB;IACD,OAAO,EAAE;QACL,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,GAAG,EAAE,MAAM,CAAC,gBAAgB;QAC5B,OAAO,EAAE,MAAM,CAAC,kBAAkB;QAClC,QAAQ,EAAE,OAAO;KACpB;CACJ,CAAC,CAAC;AAcH,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAqD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACjG,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC3B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAE5B,OAAO,CACH,MAAC,aAAa,IACV,IAAI,EAAE,WAAW,EACjB,YAAY,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EACpD,WAAW,EAAE;YACT,KAAK,EAAE,OAAO;YACd,gBAAgB,EAAE,QAAQ,CAAC,IAAI;YAC/B,QAAQ,EAAE,IAAI;SACjB,EACD,SAAS,mBAET,KAAC,cAAc,IAAC,wBAAwB,kBAAE,KAAK,CAAC,OAAO,IAAI,KAAC,MAAM,IAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,GAAI,GAAkB,EACxJ,KAAC,cAAc,IAAC,SAAS,EAAE,OAAO,CAAC,OAAO,YACtC,cAAK,SAAS,EAAE,OAAO,CAAC,OAAO,YAAG,QAAQ,GAAO,GACpC,IACL,CACnB,CAAC;AACN,CAAC,CAAC,CAAC","sourcesContent":["import type { PropsWithChildren, ReactElement } from \"react\";\r\nimport { forwardRef, useState } from \"react\";\r\nimport { Popover as FluentPopover, PopoverTrigger, PopoverSurface, makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\nimport { Button } from \"shared-ui-components/fluent/primitives/button\";\r\n\r\nconst useStyles = makeStyles({\r\n surface: {\r\n maxWidth: \"400px\",\r\n },\r\n content: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: tokens.spacingVerticalM,\r\n padding: tokens.spacingHorizontalL,\r\n minWidth: \"300px\",\r\n },\r\n});\r\n\r\ntype PopoverWithIconProps = {\r\n icon: FluentIcon;\r\n trigger?: never;\r\n};\r\n\r\ntype PopoverWithTriggerProps = {\r\n icon?: never;\r\n trigger: ReactElement;\r\n};\r\n\r\ntype PopoverProps = PopoverWithIconProps | PopoverWithTriggerProps;\r\n\r\nexport const Popover = forwardRef<HTMLButtonElement, PropsWithChildren<PopoverProps>>((props, ref) => {\r\n const { children } = props;\r\n const [popoverOpen, setPopoverOpen] = useState(false);\r\n const classes = useStyles();\r\n\r\n return (\r\n <FluentPopover\r\n open={popoverOpen}\r\n onOpenChange={(_, data) => setPopoverOpen(data.open)}\r\n positioning={{\r\n align: \"start\",\r\n overflowBoundary: document.body,\r\n autoSize: true,\r\n }}\r\n trapFocus\r\n >\r\n <PopoverTrigger disableButtonEnhancement>{props.trigger ?? <Button ref={ref} icon={props.icon} onClick={() => setPopoverOpen(true)} />}</PopoverTrigger>\r\n <PopoverSurface className={classes.surface}>\r\n <div className={classes.content}>{children}</div>\r\n </PopoverSurface>\r\n </FluentPopover>\r\n );\r\n});\r\n"]}
1
+ {"version":3,"file":"popover.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/popover.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAG1H,OAAO,EAAE,MAAM,EAAE,MAAM,+CAA+C,CAAC;AAEvE,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,OAAO,EAAE;QACL,QAAQ,EAAE,OAAO;KACpB;IACD,OAAO,EAAE;QACL,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,GAAG,EAAE,MAAM,CAAC,gBAAgB;QAC5B,OAAO,EAAE,MAAM,CAAC,kBAAkB;QAClC,QAAQ,EAAE,OAAO;KACpB;CACJ,CAAC,CAAC;AAyBH,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAqD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACjG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;IAC9F,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAE5B,MAAM,YAAY,GAAG,cAAc,KAAK,SAAS,CAAC;IAClD,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC;IAEjE,MAAM,gBAAgB,GAAG,CAAC,CAAU,EAAE,IAAuB,EAAE,EAAE;QAC7D,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,OAAO,CACH,MAAC,aAAa,IACV,IAAI,EAAE,WAAW,EACjB,YAAY,EAAE,gBAAgB,EAC9B,WAAW,EACP,WAAW,IAAI;YACX,KAAK,EAAE,OAAO;YACd,gBAAgB,EAAE,QAAQ,CAAC,IAAI;YAC/B,QAAQ,EAAE,IAAI;SACjB,aAGL,KAAC,cAAc,IAAC,wBAAwB,kBACnC,KAAK,CAAC,OAAO,IAAI,KAAC,MAAM,IAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAI,GAClG,EACjB,KAAC,cAAc,IAAC,SAAS,EAAE,gBAAgB,IAAI,OAAO,CAAC,OAAO,YAC1D,cAAK,SAAS,EAAE,OAAO,CAAC,OAAO,YAAG,QAAQ,GAAO,GACpC,IACL,CACnB,CAAC;AACN,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC","sourcesContent":["import type { PropsWithChildren, ReactElement } from \"react\";\r\nimport { forwardRef, useState } from \"react\";\r\nimport { Popover as FluentPopover, PopoverTrigger, PopoverSurface, makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport type { PositioningShorthand } from \"@fluentui/react-components\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\nimport { Button } from \"shared-ui-components/fluent/primitives/button\";\r\n\r\nconst useStyles = makeStyles({\r\n surface: {\r\n maxWidth: \"400px\",\r\n },\r\n content: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: tokens.spacingVerticalM,\r\n padding: tokens.spacingHorizontalL,\r\n minWidth: \"300px\",\r\n },\r\n});\r\n\r\ntype PopoverWithIconProps = {\r\n icon: FluentIcon;\r\n trigger?: never;\r\n};\r\n\r\ntype PopoverWithTriggerProps = {\r\n icon?: never;\r\n trigger: ReactElement;\r\n};\r\n\r\ntype PopoverBaseProps = {\r\n /** Controlled open state */\r\n open?: boolean;\r\n /** Callback when open state changes */\r\n onOpenChange?: (open: boolean) => void;\r\n /** Positioning of the popover */\r\n positioning?: PositioningShorthand;\r\n /** Custom class for the surface */\r\n surfaceClassName?: string;\r\n};\r\n\r\ntype PopoverProps = PopoverBaseProps & (PopoverWithIconProps | PopoverWithTriggerProps);\r\n\r\nexport const Popover = forwardRef<HTMLButtonElement, PropsWithChildren<PopoverProps>>((props, ref) => {\r\n const { children, open: controlledOpen, onOpenChange, positioning, surfaceClassName } = props;\r\n const [internalOpen, setInternalOpen] = useState(false);\r\n const classes = useStyles();\r\n\r\n const isControlled = controlledOpen !== undefined;\r\n const popoverOpen = isControlled ? controlledOpen : internalOpen;\r\n\r\n const handleOpenChange = (_: unknown, data: { open: boolean }) => {\r\n if (!isControlled) {\r\n setInternalOpen(data.open);\r\n }\r\n onOpenChange?.(data.open);\r\n };\r\n\r\n return (\r\n <FluentPopover\r\n open={popoverOpen}\r\n onOpenChange={handleOpenChange}\r\n positioning={\r\n positioning ?? {\r\n align: \"start\",\r\n overflowBoundary: document.body,\r\n autoSize: true,\r\n }\r\n }\r\n >\r\n <PopoverTrigger disableButtonEnhancement>\r\n {props.trigger ?? <Button ref={ref} icon={props.icon} onClick={() => handleOpenChange(null, { open: true })} />}\r\n </PopoverTrigger>\r\n <PopoverSurface className={surfaceClassName ?? classes.surface}>\r\n <div className={classes.content}>{children}</div>\r\n </PopoverSurface>\r\n </FluentPopover>\r\n );\r\n});\r\n\r\nPopover.displayName = \"Popover\";\r\n"]}
@@ -47,7 +47,7 @@ export const SyncedSliderInput = (props) => {
47
47
  const { infoLabel, ...passthroughProps } = props;
48
48
  const classes = useSyncedSliderStyles();
49
49
  const { size } = useContext(ToolContext);
50
- const [value, setValue] = useState(props.value);
50
+ const [value, setValue] = useState(props.value ?? 0);
51
51
  const pendingValueRef = useRef(undefined);
52
52
  const isDraggingRef = useRef(false);
53
53
  // NOTE: The Fluent slider will add tick marks if the step prop is anything other than undefined.
@@ -57,7 +57,7 @@ export const SyncedSliderInput = (props) => {
57
57
  const max = props.max ?? 100;
58
58
  const step = props.step ?? 1;
59
59
  useEffect(() => {
60
- !isDraggingRef.current && setValue(props.value ?? ""); // Update local state when props.value changes as long as user is not actively dragging
60
+ !isDraggingRef.current && setValue(props.value ?? 0); // Update local state when props.value changes as long as user is not actively dragging
61
61
  }, [props.value]);
62
62
  const handleSliderChange = (_, data) => {
63
63
  const newValue = data.value * step;
@@ -1 +1 @@
1
- {"version":3,"file":"syncedSlider.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/syncedSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { SliderOnChangeData } from \"@fluentui/react-components\";\r\nimport { makeStyles, Slider } from \"@fluentui/react-components\";\r\nimport { SpinButton } from \"./spinButton\";\r\nimport type { ChangeEvent, FunctionComponent } from \"react\";\r\nimport { useEffect, useState, useRef, useContext } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nconst useSyncedSliderStyles = makeStyles({\r\n container: { display: \"flex\", minWidth: 0 },\r\n syncedSlider: {\r\n flex: \"1 1 0\",\r\n flexDirection: \"row\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n minWidth: 0,\r\n },\r\n slider: {\r\n flex: \"1 1 auto\",\r\n minWidth: \"75px\",\r\n maxWidth: \"75px\",\r\n },\r\n compactSlider: {\r\n flex: \"1 1 auto\",\r\n minWidth: \"50px\", // Allow shrinking for compact mode\r\n maxWidth: \"75px\",\r\n },\r\n growSlider: {\r\n flex: \"1 1 auto\",\r\n minWidth: \"50px\",\r\n // No maxWidth - slider grows to fill available space\r\n },\r\n compactSpinButton: {\r\n width: \"65px\",\r\n minWidth: \"65px\",\r\n maxWidth: \"65px\",\r\n },\r\n compactSpinButtonInput: {\r\n minWidth: \"0\",\r\n },\r\n});\r\n\r\nexport type SyncedSliderProps = PrimitiveProps<number> & {\r\n /** Minimum value for the slider */\r\n min?: number;\r\n /** Maximum value for the slider */\r\n max?: number;\r\n /** Step size for the slider */\r\n step?: number;\r\n /** Displayed in the ux to indicate unit of measurement */\r\n unit?: string;\r\n /** When true, onChange is only called when the user releases the slider, not during drag */\r\n notifyOnlyOnRelease?: boolean;\r\n /** When true, slider grows to fill space and SpinButton is fixed at 65px */\r\n compact?: boolean;\r\n /** When true, slider grows to fill all available space (no maxWidth constraint) */\r\n growSlider?: boolean;\r\n};\r\n\r\n/**\r\n * Component which synchronizes a slider and an input field, allowing the user to change the value using either control\r\n * @param props\r\n * @returns SyncedSlider component\r\n */\r\nexport const SyncedSliderInput: FunctionComponent<SyncedSliderProps> = (props) => {\r\n SyncedSliderInput.displayName = \"SyncedSliderInput\";\r\n const { infoLabel, ...passthroughProps } = props;\r\n const classes = useSyncedSliderStyles();\r\n const { size } = useContext(ToolContext);\r\n const [value, setValue] = useState<number>(props.value);\r\n const pendingValueRef = useRef<number>(undefined);\r\n const isDraggingRef = useRef(false);\r\n\r\n // NOTE: The Fluent slider will add tick marks if the step prop is anything other than undefined.\r\n // To avoid this, we scale the min/max based on the step so we can always make step undefined.\r\n // The actual step size in the Fluent slider is 1 when it is ste to undefined.\r\n const min = props.min ?? 0;\r\n const max = props.max ?? 100;\r\n const step = props.step ?? 1;\r\n\r\n useEffect(() => {\r\n !isDraggingRef.current && setValue(props.value ?? \"\"); // Update local state when props.value changes as long as user is not actively dragging\r\n }, [props.value]);\r\n\r\n const handleSliderChange = (_: ChangeEvent<HTMLInputElement>, data: SliderOnChangeData) => {\r\n const newValue = data.value * step;\r\n setValue(newValue);\r\n\r\n if (props.notifyOnlyOnRelease) {\r\n // Store the value but don't notify parent yet\r\n pendingValueRef.current = newValue;\r\n } else {\r\n // Notify parent as slider changes\r\n props.onChange(newValue);\r\n }\r\n };\r\n\r\n const handleSliderPointerDown = () => {\r\n isDraggingRef.current = true;\r\n };\r\n\r\n const handleSliderPointerUp = () => {\r\n if (props.notifyOnlyOnRelease && isDraggingRef.current && pendingValueRef.current !== undefined) {\r\n props.onChange(pendingValueRef.current);\r\n pendingValueRef.current = undefined;\r\n }\r\n isDraggingRef.current = false;\r\n };\r\n\r\n const handleInputChange = (value: number) => {\r\n setValue(value);\r\n props.onChange(value); // Input always updates immediately\r\n };\r\n\r\n const hasSlider = props.min !== undefined && props.max !== undefined;\r\n\r\n // Determine Slider className based on props\r\n const getSliderClassName = () => {\r\n if (props.growSlider) {\r\n return classes.growSlider;\r\n }\r\n if (props.compact) {\r\n return classes.compactSlider;\r\n }\r\n return classes.slider;\r\n };\r\n\r\n return (\r\n <div className={classes.container}>\r\n {infoLabel && <InfoLabel {...infoLabel} htmlFor={\"syncedSlider\"} />}\r\n <div id=\"syncedSlider\" className={classes.syncedSlider}>\r\n {hasSlider && (\r\n <Slider\r\n {...passthroughProps}\r\n className={getSliderClassName()}\r\n size={size}\r\n min={min / step}\r\n max={max / step}\r\n step={undefined}\r\n value={value / step}\r\n onChange={handleSliderChange}\r\n onPointerDown={handleSliderPointerDown}\r\n onPointerUp={handleSliderPointerUp}\r\n />\r\n )}\r\n <SpinButton\r\n {...passthroughProps}\r\n className={hasSlider || props.compact ? classes.compactSpinButton : undefined}\r\n inputClassName={hasSlider || props.compact ? classes.compactSpinButtonInput : undefined}\r\n value={value}\r\n onChange={handleInputChange}\r\n step={props.step}\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n"]}
1
+ {"version":3,"file":"syncedSlider.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/syncedSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { SliderOnChangeData } from \"@fluentui/react-components\";\r\nimport { makeStyles, Slider } from \"@fluentui/react-components\";\r\nimport { SpinButton } from \"./spinButton\";\r\nimport type { ChangeEvent, FunctionComponent } from \"react\";\r\nimport { useEffect, useState, useRef, useContext } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nconst useSyncedSliderStyles = makeStyles({\r\n container: { display: \"flex\", minWidth: 0 },\r\n syncedSlider: {\r\n flex: \"1 1 0\",\r\n flexDirection: \"row\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n minWidth: 0,\r\n },\r\n slider: {\r\n flex: \"1 1 auto\",\r\n minWidth: \"75px\",\r\n maxWidth: \"75px\",\r\n },\r\n compactSlider: {\r\n flex: \"1 1 auto\",\r\n minWidth: \"50px\", // Allow shrinking for compact mode\r\n maxWidth: \"75px\",\r\n },\r\n growSlider: {\r\n flex: \"1 1 auto\",\r\n minWidth: \"50px\",\r\n // No maxWidth - slider grows to fill available space\r\n },\r\n compactSpinButton: {\r\n width: \"65px\",\r\n minWidth: \"65px\",\r\n maxWidth: \"65px\",\r\n },\r\n compactSpinButtonInput: {\r\n minWidth: \"0\",\r\n },\r\n});\r\n\r\nexport type SyncedSliderProps = PrimitiveProps<number> & {\r\n /** Minimum value for the slider */\r\n min?: number;\r\n /** Maximum value for the slider */\r\n max?: number;\r\n /** Step size for the slider */\r\n step?: number;\r\n /** Displayed in the ux to indicate unit of measurement */\r\n unit?: string;\r\n /** When true, onChange is only called when the user releases the slider, not during drag */\r\n notifyOnlyOnRelease?: boolean;\r\n /** When true, slider grows to fill space and SpinButton is fixed at 65px */\r\n compact?: boolean;\r\n /** When true, slider grows to fill all available space (no maxWidth constraint) */\r\n growSlider?: boolean;\r\n};\r\n\r\n/**\r\n * Component which synchronizes a slider and an input field, allowing the user to change the value using either control\r\n * @param props\r\n * @returns SyncedSlider component\r\n */\r\nexport const SyncedSliderInput: FunctionComponent<SyncedSliderProps> = (props) => {\r\n SyncedSliderInput.displayName = \"SyncedSliderInput\";\r\n const { infoLabel, ...passthroughProps } = props;\r\n const classes = useSyncedSliderStyles();\r\n const { size } = useContext(ToolContext);\r\n const [value, setValue] = useState<number>(props.value ?? 0);\r\n const pendingValueRef = useRef<number>(undefined);\r\n const isDraggingRef = useRef(false);\r\n\r\n // NOTE: The Fluent slider will add tick marks if the step prop is anything other than undefined.\r\n // To avoid this, we scale the min/max based on the step so we can always make step undefined.\r\n // The actual step size in the Fluent slider is 1 when it is ste to undefined.\r\n const min = props.min ?? 0;\r\n const max = props.max ?? 100;\r\n const step = props.step ?? 1;\r\n\r\n useEffect(() => {\r\n !isDraggingRef.current && setValue(props.value ?? 0); // Update local state when props.value changes as long as user is not actively dragging\r\n }, [props.value]);\r\n\r\n const handleSliderChange = (_: ChangeEvent<HTMLInputElement>, data: SliderOnChangeData) => {\r\n const newValue = data.value * step;\r\n setValue(newValue);\r\n\r\n if (props.notifyOnlyOnRelease) {\r\n // Store the value but don't notify parent yet\r\n pendingValueRef.current = newValue;\r\n } else {\r\n // Notify parent as slider changes\r\n props.onChange(newValue);\r\n }\r\n };\r\n\r\n const handleSliderPointerDown = () => {\r\n isDraggingRef.current = true;\r\n };\r\n\r\n const handleSliderPointerUp = () => {\r\n if (props.notifyOnlyOnRelease && isDraggingRef.current && pendingValueRef.current !== undefined) {\r\n props.onChange(pendingValueRef.current);\r\n pendingValueRef.current = undefined;\r\n }\r\n isDraggingRef.current = false;\r\n };\r\n\r\n const handleInputChange = (value: number) => {\r\n setValue(value);\r\n props.onChange(value); // Input always updates immediately\r\n };\r\n\r\n const hasSlider = props.min !== undefined && props.max !== undefined;\r\n\r\n // Determine Slider className based on props\r\n const getSliderClassName = () => {\r\n if (props.growSlider) {\r\n return classes.growSlider;\r\n }\r\n if (props.compact) {\r\n return classes.compactSlider;\r\n }\r\n return classes.slider;\r\n };\r\n\r\n return (\r\n <div className={classes.container}>\r\n {infoLabel && <InfoLabel {...infoLabel} htmlFor={\"syncedSlider\"} />}\r\n <div id=\"syncedSlider\" className={classes.syncedSlider}>\r\n {hasSlider && (\r\n <Slider\r\n {...passthroughProps}\r\n className={getSliderClassName()}\r\n size={size}\r\n min={min / step}\r\n max={max / step}\r\n step={undefined}\r\n value={value / step}\r\n onChange={handleSliderChange}\r\n onPointerDown={handleSliderPointerDown}\r\n onPointerUp={handleSliderPointerUp}\r\n />\r\n )}\r\n <SpinButton\r\n {...passthroughProps}\r\n className={hasSlider || props.compact ? classes.compactSpinButton : undefined}\r\n inputClassName={hasSlider || props.compact ? classes.compactSpinButtonInput : undefined}\r\n value={value}\r\n onChange={handleInputChange}\r\n step={props.step}\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onerjs/shared-ui-components",
3
- "version": "8.36.1",
3
+ "version": "8.36.3",
4
4
  "main": "index.js",
5
5
  "module": "index.js",
6
6
  "types": "index.d.ts",