@onerjs/shared-ui-components 8.35.8 → 8.36.1

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.
@@ -5,8 +5,8 @@ type GradientListProps<T extends FactorGradient | Color3Gradient | Color4Gradien
5
5
  label: string;
6
6
  gradients: Nullable<Array<T>>;
7
7
  addGradient: (step?: T) => void;
8
- removeGradient: (step: T) => void;
9
- onChange: (newGradient: T) => void;
8
+ removeGradient: (step: T, index: number) => void;
9
+ onChange: (newGradient: T, index: number) => void;
10
10
  };
11
11
  export declare const FactorGradientList: FunctionComponent<GradientListProps<FactorGradient>>;
12
12
  export declare const Color3GradientList: FunctionComponent<GradientListProps<Color3Gradient>>;
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
2
3
  import { List } from "../primitives/list.js";
3
4
  import { Color3GradientComponent, Color4GradientComponent, FactorGradientComponent } from "../primitives/gradient.js";
4
5
  import { Color3Gradient, ColorGradient as Color4Gradient, FactorGradient } from "@onerjs/core/Misc/gradients.js";
@@ -14,59 +15,59 @@ function GradientsToListItems(gradients) {
14
15
  export const FactorGradientList = (props) => {
15
16
  FactorGradientList.displayName = "FactorGradientList";
16
17
  const { gradients } = props;
17
- const items = GradientsToListItems(gradients);
18
- return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
18
+ const items = useMemo(() => GradientsToListItems(gradients), [gradients]);
19
+ return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item, index) => props.removeGradient(item.data, index), onAdd: () => {
19
20
  if (items.length === 0) {
20
21
  props.addGradient(); // Default
21
22
  }
22
23
  else {
23
24
  props.addGradient(new FactorGradient(1, 1, 1));
24
25
  }
25
- }, renderItem: (item) => {
26
+ }, renderItem: (item, index) => {
26
27
  return (_jsx(FactorGradientComponent, { value: item.data, onChange: (newGradient) => {
27
28
  item.data.gradient = newGradient.gradient;
28
29
  item.data.factor1 = newGradient.factor1;
29
30
  item.data.factor2 = newGradient.factor2;
30
- props.onChange(newGradient);
31
+ props.onChange(newGradient, index);
31
32
  } }));
32
33
  } }, "Factor"));
33
34
  };
34
35
  export const Color3GradientList = (props) => {
35
36
  Color3GradientList.displayName = "Color3GradientList";
36
37
  const { gradients } = props;
37
- const items = GradientsToListItems(gradients);
38
- return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
38
+ const items = useMemo(() => GradientsToListItems(gradients), [gradients]);
39
+ return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item, index) => props.removeGradient(item.data, index), onAdd: () => {
39
40
  if (items.length === 0) {
40
41
  props.addGradient(); // Default
41
42
  }
42
43
  else {
43
44
  props.addGradient(new Color3Gradient(1, Color3.White()));
44
45
  }
45
- }, renderItem: (item) => {
46
+ }, renderItem: (item, index) => {
46
47
  return (_jsx(Color3GradientComponent, { value: item.data, onChange: (newGradient) => {
47
48
  item.data.gradient = newGradient.gradient;
48
49
  item.data.color = newGradient.color;
49
- props.onChange(newGradient);
50
+ props.onChange(newGradient, index);
50
51
  } }));
51
52
  } }, "Color3"));
52
53
  };
53
54
  export const Color4GradientList = (props) => {
54
55
  Color4GradientList.displayName = "Color4GradientList";
55
56
  const { gradients } = props;
56
- const items = GradientsToListItems(gradients);
57
- return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
57
+ const items = useMemo(() => GradientsToListItems(gradients), [gradients]);
58
+ return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item, index) => props.removeGradient(item.data, index), onAdd: () => {
58
59
  if (items.length === 0) {
59
60
  props.addGradient(); // Default
60
61
  }
61
62
  else {
62
63
  props.addGradient(new Color4Gradient(1, new Color4(1, 1, 1, 1), new Color4(1, 1, 1, 1)));
63
64
  }
64
- }, renderItem: (item) => {
65
+ }, renderItem: (item, index) => {
65
66
  return (_jsx(Color4GradientComponent, { value: item.data, onChange: (newGradient) => {
66
67
  item.data.gradient = newGradient.gradient;
67
68
  item.data.color1 = newGradient.color1;
68
69
  item.data.color2 = newGradient.color2;
69
- props.onChange(newGradient);
70
+ props.onChange(newGradient, index);
70
71
  } }));
71
72
  } }, "Color4"));
72
73
  };
@@ -1 +1 @@
1
- {"version":3,"file":"gradientList.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/gradientList.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACnH,OAAO,EAAE,cAAc,EAAE,aAAa,IAAI,cAAc,EAAE,cAAc,EAAE,uCAA4B;AAGtG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,yCAA8B;AAUvD,iEAAiE;AACjE,SAAS,oBAAoB,CAA2B,SAA6B;IACjF,OAAO,CACH,SAAS,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACjC,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,QAAQ,CAAC,QAAQ;KAC5B,CAAC,CAAC,IAAI,EAAE,CACZ,CAAC;AACN,CAAC;AACD,MAAM,CAAC,MAAM,kBAAkB,GAAyD,CAAC,KAAK,EAAE,EAAE;IAC9F,kBAAkB,CAAC,WAAW,GAAG,oBAAoB,CAAC;IACtD,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC5B,MAAM,KAAK,GAAG,oBAAoB,CAAiB,SAAS,CAAC,CAAC;IAC9D,OAAO,CACH,KAAC,IAAI,IAED,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,GAAG,EACnF,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EACnD,KAAK,EAAE,GAAG,EAAE;YACR,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,UAAU;YACnC,CAAC;iBAAM,CAAC;gBACJ,KAAK,CAAC,WAAW,CAAC,IAAI,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC;QACL,CAAC,EACD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;YACjB,OAAO,CACH,KAAC,uBAAuB,IACpB,KAAK,EAAE,IAAI,CAAC,IAAI,EAChB,QAAQ,EAAE,CAAC,WAA2B,EAAE,EAAE;oBACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;oBAC1C,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;oBACxC,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;oBACxC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAChC,CAAC,GACH,CACL,CAAC;QACN,CAAC,IAvBG,QAAQ,CAwBd,CACL,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAyD,CAAC,KAAK,EAAE,EAAE;IAC9F,kBAAkB,CAAC,WAAW,GAAG,oBAAoB,CAAC;IACtD,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC5B,MAAM,KAAK,GAAG,oBAAoB,CAAiB,SAAS,CAAC,CAAC;IAC9D,OAAO,CACH,KAAC,IAAI,IAED,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,GAAG,EACnF,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EACnD,KAAK,EAAE,GAAG,EAAE;YACR,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,UAAU;YACnC,CAAC;iBAAM,CAAC;gBACJ,KAAK,CAAC,WAAW,CAAC,IAAI,cAAc,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC7D,CAAC;QACL,CAAC,EACD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;YACjB,OAAO,CACH,KAAC,uBAAuB,IACpB,KAAK,EAAE,IAAI,CAAC,IAAI,EAChB,QAAQ,EAAE,CAAC,WAA2B,EAAE,EAAE;oBACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;oBAC1C,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;oBACpC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAChC,CAAC,GACH,CACL,CAAC;QACN,CAAC,IAtBG,QAAQ,CAuBd,CACL,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAyD,CAAC,KAAK,EAAE,EAAE;IAC9F,kBAAkB,CAAC,WAAW,GAAG,oBAAoB,CAAC;IACtD,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC5B,MAAM,KAAK,GAAG,oBAAoB,CAAiB,SAAS,CAAC,CAAC;IAC9D,OAAO,CACH,KAAC,IAAI,IAED,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,GAAG,EACnF,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EACnD,KAAK,EAAE,GAAG,EAAE;YACR,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,UAAU;YACnC,CAAC;iBAAM,CAAC;gBACJ,KAAK,CAAC,WAAW,CAAC,IAAI,cAAc,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7F,CAAC;QACL,CAAC,EACD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;YACjB,OAAO,CACH,KAAC,uBAAuB,IACpB,KAAK,EAAE,IAAI,CAAC,IAAI,EAChB,QAAQ,EAAE,CAAC,WAA2B,EAAE,EAAE;oBACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;oBAC1C,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBACtC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBACtC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAChC,CAAC,GACH,CACL,CAAC;QACN,CAAC,IAvBG,QAAQ,CAwBd,CACL,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { FunctionComponent } from \"react\";\r\n\r\nimport { List } from \"../primitives/list\";\r\nimport { Color3GradientComponent, Color4GradientComponent, FactorGradientComponent } from \"../primitives/gradient\";\r\nimport { Color3Gradient, ColorGradient as Color4Gradient, FactorGradient } from \"core/Misc/gradients\";\r\nimport type { IValueGradient } from \"core/Misc/gradients\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\n\r\ntype GradientListProps<T extends FactorGradient | Color3Gradient | Color4Gradient> = {\r\n label: string;\r\n gradients: Nullable<Array<T>>;\r\n addGradient: (step?: T) => void;\r\n removeGradient: (step: T) => void;\r\n onChange: (newGradient: T) => void;\r\n};\r\n\r\n// Convert gradients to LineList items and sort by gradient value\r\nfunction GradientsToListItems<T extends IValueGradient>(gradients: Nullable<Array<T>>) {\r\n return (\r\n gradients?.map((gradient, index) => ({\r\n id: index,\r\n data: gradient,\r\n sortBy: gradient.gradient,\r\n })) ?? []\r\n );\r\n}\r\nexport const FactorGradientList: FunctionComponent<GradientListProps<FactorGradient>> = (props) => {\r\n FactorGradientList.displayName = \"FactorGradientList\";\r\n const { gradients } = props;\r\n const items = GradientsToListItems<FactorGradient>(gradients);\r\n return (\r\n <List\r\n key=\"Factor\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item) => props.removeGradient(item.data)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new FactorGradient(1, 1, 1));\r\n }\r\n }}\r\n renderItem={(item) => {\r\n return (\r\n <FactorGradientComponent\r\n value={item.data}\r\n onChange={(newGradient: FactorGradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.factor1 = newGradient.factor1;\r\n item.data.factor2 = newGradient.factor2;\r\n props.onChange(newGradient);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n\r\nexport const Color3GradientList: FunctionComponent<GradientListProps<Color3Gradient>> = (props) => {\r\n Color3GradientList.displayName = \"Color3GradientList\";\r\n const { gradients } = props;\r\n const items = GradientsToListItems<Color3Gradient>(gradients);\r\n return (\r\n <List\r\n key=\"Color3\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item) => props.removeGradient(item.data)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new Color3Gradient(1, Color3.White()));\r\n }\r\n }}\r\n renderItem={(item) => {\r\n return (\r\n <Color3GradientComponent\r\n value={item.data}\r\n onChange={(newGradient: Color3Gradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.color = newGradient.color;\r\n props.onChange(newGradient);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n\r\nexport const Color4GradientList: FunctionComponent<GradientListProps<Color4Gradient>> = (props) => {\r\n Color4GradientList.displayName = \"Color4GradientList\";\r\n const { gradients } = props;\r\n const items = GradientsToListItems<Color4Gradient>(gradients);\r\n return (\r\n <List\r\n key=\"Color4\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item) => props.removeGradient(item.data)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new Color4Gradient(1, new Color4(1, 1, 1, 1), new Color4(1, 1, 1, 1)));\r\n }\r\n }}\r\n renderItem={(item) => {\r\n return (\r\n <Color4GradientComponent\r\n value={item.data}\r\n onChange={(newGradient: Color4Gradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.color1 = newGradient.color1;\r\n item.data.color2 = newGradient.color2;\r\n props.onChange(newGradient);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n"]}
1
+ {"version":3,"file":"gradientList.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/gradientList.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { FunctionComponent } from \"react\";\r\n\r\nimport { useMemo } from \"react\";\r\n\r\nimport { List } from \"../primitives/list\";\r\nimport { Color3GradientComponent, Color4GradientComponent, FactorGradientComponent } from \"../primitives/gradient\";\r\nimport { Color3Gradient, ColorGradient as Color4Gradient, FactorGradient } from \"core/Misc/gradients\";\r\nimport type { IValueGradient } from \"core/Misc/gradients\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\n\r\ntype GradientListProps<T extends FactorGradient | Color3Gradient | Color4Gradient> = {\r\n label: string;\r\n gradients: Nullable<Array<T>>;\r\n addGradient: (step?: T) => void;\r\n removeGradient: (step: T, index: number) => void;\r\n onChange: (newGradient: T, index: number) => void;\r\n};\r\n\r\n// Convert gradients to LineList items and sort by gradient value\r\nfunction GradientsToListItems<T extends IValueGradient>(gradients: Nullable<Array<T>>) {\r\n return (\r\n gradients?.map((gradient, index) => ({\r\n id: index,\r\n data: gradient,\r\n sortBy: gradient.gradient,\r\n })) ?? []\r\n );\r\n}\r\nexport const FactorGradientList: FunctionComponent<GradientListProps<FactorGradient>> = (props) => {\r\n FactorGradientList.displayName = \"FactorGradientList\";\r\n const { gradients } = props;\r\n const items = useMemo(() => GradientsToListItems<FactorGradient>(gradients), [gradients]);\r\n return (\r\n <List\r\n key=\"Factor\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item, index) => props.removeGradient(item.data, index)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new FactorGradient(1, 1, 1));\r\n }\r\n }}\r\n renderItem={(item, index) => {\r\n return (\r\n <FactorGradientComponent\r\n value={item.data}\r\n onChange={(newGradient: FactorGradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.factor1 = newGradient.factor1;\r\n item.data.factor2 = newGradient.factor2;\r\n props.onChange(newGradient, index);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n\r\nexport const Color3GradientList: FunctionComponent<GradientListProps<Color3Gradient>> = (props) => {\r\n Color3GradientList.displayName = \"Color3GradientList\";\r\n const { gradients } = props;\r\n const items = useMemo(() => GradientsToListItems<Color3Gradient>(gradients), [gradients]);\r\n return (\r\n <List\r\n key=\"Color3\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item, index) => props.removeGradient(item.data, index)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new Color3Gradient(1, Color3.White()));\r\n }\r\n }}\r\n renderItem={(item, index) => {\r\n return (\r\n <Color3GradientComponent\r\n value={item.data}\r\n onChange={(newGradient: Color3Gradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.color = newGradient.color;\r\n props.onChange(newGradient, index);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n\r\nexport const Color4GradientList: FunctionComponent<GradientListProps<Color4Gradient>> = (props) => {\r\n Color4GradientList.displayName = \"Color4GradientList\";\r\n const { gradients } = props;\r\n const items = useMemo(() => GradientsToListItems<Color4Gradient>(gradients), [gradients]);\r\n return (\r\n <List\r\n key=\"Color4\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item, index) => props.removeGradient(item.data, index)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new Color4Gradient(1, new Color4(1, 1, 1, 1), new Color4(1, 1, 1, 1)));\r\n }\r\n }}\r\n renderItem={(item, index) => {\r\n return (\r\n <Color4GradientComponent\r\n value={item.data}\r\n onChange={(newGradient: Color4Gradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.color1 = newGradient.color1;\r\n item.data.color2 = newGradient.color2;\r\n props.onChange(newGradient, index);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n"]}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Body1, Checkbox, makeStyles, tokens, mergeClasses, Tooltip } from "@fluentui/react-components";
3
- import { ChevronCircleDown20Regular, ChevronCircleDown16Regular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, Copy16Regular, Copy20Regular, } from "@fluentui/react-icons";
3
+ import { ChevronCircleDown20Regular, ChevronCircleDown16Regular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, CopyRegular, Copy16Regular, } from "@fluentui/react-icons";
4
4
  import { useContext, useState, forwardRef, cloneElement, isValidElement, useRef } from "react";
5
5
  import { Collapse } from "../../primitives/collapse.js";
6
6
  import { copyCommandToClipboard } from "../../../copyCommandToClipboard.js";
@@ -8,7 +8,7 @@ import { ToolContext } from "../fluentToolWrapper.js";
8
8
  import { Link } from "../../primitives/link.js";
9
9
  import { ToggleButton } from "../../primitives/toggleButton.js";
10
10
  import { Button } from "../../primitives/button.js";
11
- import { CustomTokens } from "../../primitives/utils.js";
11
+ import { CustomTokens, TokenMap } from "../../primitives/utils.js";
12
12
  import { InfoLabel } from "../../primitives/infoLabel.js";
13
13
  const usePropertyLineStyles = makeStyles({
14
14
  baseLine: {
@@ -50,6 +50,12 @@ const usePropertyLineStyles = makeStyles({
50
50
  checkbox: {
51
51
  display: "flex",
52
52
  alignItems: "center",
53
+ marginRight: tokens.spacingHorizontalXS,
54
+ },
55
+ checkboxIndicator: {
56
+ margin: TokenMap.px2,
57
+ width: TokenMap.px12,
58
+ height: TokenMap.px12,
53
59
  },
54
60
  });
55
61
  /**
@@ -78,7 +84,7 @@ export const PropertyLine = forwardRef((props, ref) => {
78
84
  : children;
79
85
  return (_jsxs(LineContainer, { ref: ref, children: [_jsxs("div", { className: classes.baseLine, children: [_jsx(InfoLabel, { className: classes.infoLabel, htmlFor: "property", info: description, label: label, flexLabel: true }), _jsxs("div", { className: classes.rightContent, id: "property", children: [expandedContent && (_jsx(ToggleButton, { title: "Expand/Collapse property", appearance: "transparent", checkedIcon: size === "small" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular, uncheckedIcon: size === "small" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular, value: expanded === true, onChange: setExpanded })), nullable && !ignoreNullable && (
80
86
  // If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')
81
- _jsx(Tooltip, { relationship: "label", content: props.value == null ? "Enable property" : "Disable property (set to null)", children: _jsx(Checkbox, { className: classes.checkbox, checked: !(props.value == null), onChange: (_, data) => {
87
+ _jsx(Tooltip, { relationship: "label", content: props.value == null ? "Enable property" : "Disable property (set to null)", children: _jsx(Checkbox, { className: classes.checkbox, indicator: { className: classes.checkboxIndicator }, checked: !(props.value == null), onChange: (_, data) => {
82
88
  if (data.checked) {
83
89
  // if checked this means we are returning to non-null, use cached value if exists. If no cached value, use default value
84
90
  cachedVal.current != null ? props.onChange(cachedVal.current) : props.onChange(props.defaultValue);
@@ -88,7 +94,7 @@ export const PropertyLine = forwardRef((props, ref) => {
88
94
  cachedVal.current = props.value;
89
95
  props.onChange(null);
90
96
  }
91
- } }) })), _jsx("div", { className: classes.childWrapper, children: processedChildren }), onCopy && !disableCopy && (_jsx(Button, { className: classes.copy, title: "Copy to clipboard", appearance: "transparent", icon: size === "small" ? Copy16Regular : Copy20Regular, onClick: () => copyCommandToClipboard(onCopy()) }))] })] }), expandedContent && (_jsx(Collapse, { visible: !!expanded, children: _jsx("div", { className: classes.expandedContentDiv, children: expandedContent }) }))] }));
97
+ } }) })), _jsx("div", { className: classes.childWrapper, children: processedChildren }), onCopy && !disableCopy && (_jsx(Button, { className: classes.copy, title: "Copy to clipboard", appearance: "transparent", icon: size === "small" ? Copy16Regular : CopyRegular, onClick: () => copyCommandToClipboard(onCopy()) }))] })] }), expandedContent && (_jsx(Collapse, { visible: !!expanded, children: _jsx("div", { className: classes.expandedContentDiv, children: expandedContent }) }))] }));
92
98
  });
93
99
  const useLineStyles = makeStyles({
94
100
  container: {
@@ -100,6 +106,12 @@ const useLineStyles = makeStyles({
100
106
  justifyContent: "center",
101
107
  paddingTop: tokens.spacingVerticalXXS,
102
108
  paddingBottom: tokens.spacingVerticalXXS,
109
+ borderTop: `1px solid transparent`,
110
+ borderBottom: `1px solid transparent`,
111
+ ":hover": {
112
+ borderTopColor: tokens.colorNeutralStroke2,
113
+ borderBottomColor: tokens.colorNeutralStroke2,
114
+ },
103
115
  },
104
116
  containerSmall: {
105
117
  minHeight: CustomTokens.lineHeightSmall,
@@ -1 +1 @@
1
- {"version":3,"file":"propertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/propertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Body1, Checkbox, makeStyles, tokens, mergeClasses, Tooltip } from \"@fluentui/react-components\";\r\nimport {\r\n ChevronCircleDown20Regular,\r\n ChevronCircleDown16Regular,\r\n ChevronCircleRight16Regular,\r\n ChevronCircleRight20Regular,\r\n Copy16Regular,\r\n Copy20Regular,\r\n} from \"@fluentui/react-icons\";\r\nimport type { FunctionComponent, HTMLProps, PropsWithChildren } from \"react\";\r\nimport { useContext, useState, forwardRef, cloneElement, isValidElement, useRef } from \"react\";\r\nimport { Collapse } from \"../../primitives/collapse\";\r\nimport { copyCommandToClipboard } from \"../../../copyCommandToClipboard\";\r\nimport { ToolContext } from \"../fluentToolWrapper\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport { Link } from \"../../primitives/link\";\r\nimport { ToggleButton } from \"../../primitives/toggleButton\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { CustomTokens } from \"../../primitives/utils\";\r\nimport { InfoLabel } from \"../../primitives/infoLabel\";\r\n\r\nconst usePropertyLineStyles = makeStyles({\r\n baseLine: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n width: \"100%\",\r\n },\r\n infoLabel: {\r\n display: \"flex\",\r\n flex: \"1 1 0\", // grow=1, shrink =1, basis = 0 initial size before\r\n minWidth: CustomTokens.labelMinWidth,\r\n textAlign: \"left\",\r\n },\r\n rightContent: {\r\n flex: \"0 1 auto\",\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-end\",\r\n },\r\n childWrapper: {\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n infoPopup: {\r\n whiteSpace: \"normal\",\r\n wordBreak: \"break-word\",\r\n },\r\n copy: {\r\n marginRight: CustomTokens.rightAlignOffset, // Accounts for the padding baked into fluent button / ensures propertyLine looks visually aligned at the right\r\n },\r\n expandedContentDiv: {\r\n overflow: \"hidden\",\r\n },\r\n checkbox: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n },\r\n});\r\n\r\ntype BasePropertyLineProps = {\r\n /**\r\n * The name of the property to display in the property line.\r\n */\r\n label: string;\r\n /**\r\n * Optional description for the property, shown on hover of the info icon\r\n */\r\n description?: string;\r\n /**\r\n * Optional function returning a string to copy to clipboard.\r\n */\r\n onCopy?: () => string;\r\n /**\r\n * Link to the documentation for this property, available from the info icon either linked from the description (if provided) or default 'docs' text\r\n */\r\n docLink?: string;\r\n};\r\n\r\n// Only require value/onChange/defaultValue props if nullable is true\r\ntype NullableProperty<ValueT> = {\r\n nullable: true;\r\n ignoreNullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue?: ValueT;\r\n};\r\n\r\ntype IgnoreNullable<ValueT> = {\r\n ignoreNullable: true;\r\n nullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue: ValueT;\r\n};\r\n\r\ntype NonNullableProperty = {\r\n nullable?: false;\r\n ignoreNullable?: false;\r\n};\r\n\r\n// Only expect optional expandByDefault prop if expandedContent is defined\r\ntype ExpandableProperty = {\r\n /**\r\n * If supplied, an 'expand' icon will be shown which, when clicked, renders this component within the property line.\r\n */\r\n expandedContent: JSX.Element;\r\n\r\n /**\r\n * If true, the expanded content will be shown by default.\r\n */\r\n expandByDefault?: boolean;\r\n};\r\n\r\n// If expanded content is undefined, don't expect expandByDefault prop\r\ntype NonExpandableProperty = {\r\n expandedContent?: undefined;\r\n};\r\n\r\nexport type PropertyLineProps<ValueT> = BasePropertyLineProps &\r\n (NullableProperty<ValueT> | NonNullableProperty | IgnoreNullable<ValueT>) &\r\n (ExpandableProperty | NonExpandableProperty);\r\n\r\n/**\r\n * A reusable component that renders a property line with a label and child content, and an optional description, copy button, and expandable section.\r\n *\r\n * @param props - The properties for the PropertyLine component.\r\n * @returns A React element representing the property line.\r\n *\r\n */\r\nexport const PropertyLine = forwardRef<HTMLDivElement, PropsWithChildren<PropertyLineProps<any>>>((props, ref) => {\r\n PropertyLine.displayName = \"PropertyLine\";\r\n const { disableCopy, size } = useContext(ToolContext);\r\n const classes = usePropertyLineStyles();\r\n const { label, onCopy, expandedContent, children, nullable, ignoreNullable } = props;\r\n\r\n const [expanded, setExpanded] = useState(\"expandByDefault\" in props ? props.expandByDefault : false);\r\n const cachedVal = useRef(nullable ? props.value : null);\r\n\r\n const description = props.docLink ? <Link url={props.docLink} value={props.description ?? \"Docs\"} /> : props.description ? <Body1>{props.description}</Body1> : undefined;\r\n\r\n // Process children to handle nullable state -- creating component in disabled state with default value in lieu of null value\r\n const processedChildren =\r\n (nullable || ignoreNullable) && isValidElement(children)\r\n ? cloneElement(children, {\r\n ...children.props,\r\n disabled: children.props.disabled || (nullable && props.value == null),\r\n value: props.value ?? props.defaultValue,\r\n defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state\r\n })\r\n : children;\r\n\r\n return (\r\n <LineContainer ref={ref}>\r\n <div className={classes.baseLine}>\r\n <InfoLabel className={classes.infoLabel} htmlFor=\"property\" info={description} label={label} flexLabel />\r\n <div className={classes.rightContent} id=\"property\">\r\n {expandedContent && (\r\n <ToggleButton\r\n title=\"Expand/Collapse property\"\r\n appearance=\"transparent\"\r\n checkedIcon={size === \"small\" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular}\r\n uncheckedIcon={size === \"small\" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular}\r\n value={expanded === true}\r\n onChange={setExpanded}\r\n />\r\n )}\r\n\r\n {nullable && !ignoreNullable && (\r\n // If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')\r\n <Tooltip relationship=\"label\" content={props.value == null ? \"Enable property\" : \"Disable property (set to null)\"}>\r\n <Checkbox\r\n className={classes.checkbox}\r\n checked={!(props.value == null)}\r\n onChange={(_, data) => {\r\n if (data.checked) {\r\n // if checked this means we are returning to non-null, use cached value if exists. If no cached value, use default value\r\n cachedVal.current != null ? props.onChange(cachedVal.current) : props.onChange(props.defaultValue);\r\n } else {\r\n // if moving to un-checked state, this means moving to null value. Cache the old value and tell props.onChange(null)\r\n cachedVal.current = props.value;\r\n props.onChange(null);\r\n }\r\n }}\r\n />\r\n </Tooltip>\r\n )}\r\n <div className={classes.childWrapper}>{processedChildren}</div>\r\n {onCopy && !disableCopy && (\r\n <Button\r\n className={classes.copy}\r\n title=\"Copy to clipboard\"\r\n appearance=\"transparent\"\r\n icon={size === \"small\" ? Copy16Regular : Copy20Regular}\r\n onClick={() => copyCommandToClipboard(onCopy())}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n {expandedContent && (\r\n <Collapse visible={!!expanded}>\r\n <div className={classes.expandedContentDiv}>{expandedContent}</div>\r\n </Collapse>\r\n )}\r\n </LineContainer>\r\n );\r\n});\r\n\r\nconst useLineStyles = makeStyles({\r\n container: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\", // Stack line + expanded content\r\n minHeight: CustomTokens.lineHeight,\r\n boxSizing: \"border-box\",\r\n justifyContent: \"center\",\r\n paddingTop: tokens.spacingVerticalXXS,\r\n paddingBottom: tokens.spacingVerticalXXS,\r\n },\r\n containerSmall: {\r\n minHeight: CustomTokens.lineHeightSmall,\r\n },\r\n});\r\n\r\nexport const LineContainer = forwardRef<HTMLDivElement, PropsWithChildren<HTMLProps<HTMLDivElement>>>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const classes = useLineStyles();\r\n\r\n return (\r\n <div ref={ref} className={mergeClasses(classes.container, size == \"small\" ? classes.containerSmall : undefined)} {...props}>\r\n {props.children}\r\n </div>\r\n );\r\n});\r\n\r\nexport const PlaceholderPropertyLine: FunctionComponent<PrimitiveProps<any> & PropertyLineProps<any>> = (props) => {\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1>{props.value}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
1
+ {"version":3,"file":"propertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/propertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Body1, Checkbox, makeStyles, tokens, mergeClasses, Tooltip } from \"@fluentui/react-components\";\r\nimport {\r\n ChevronCircleDown20Regular,\r\n ChevronCircleDown16Regular,\r\n ChevronCircleRight16Regular,\r\n ChevronCircleRight20Regular,\r\n CopyRegular,\r\n Copy16Regular,\r\n} from \"@fluentui/react-icons\";\r\nimport type { FunctionComponent, HTMLProps, PropsWithChildren } from \"react\";\r\nimport { useContext, useState, forwardRef, cloneElement, isValidElement, useRef } from \"react\";\r\nimport { Collapse } from \"../../primitives/collapse\";\r\nimport { copyCommandToClipboard } from \"../../../copyCommandToClipboard\";\r\nimport { ToolContext } from \"../fluentToolWrapper\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport { Link } from \"../../primitives/link\";\r\nimport { ToggleButton } from \"../../primitives/toggleButton\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { CustomTokens, TokenMap } from \"../../primitives/utils\";\r\nimport { InfoLabel } from \"../../primitives/infoLabel\";\r\n\r\nconst usePropertyLineStyles = makeStyles({\r\n baseLine: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n width: \"100%\",\r\n },\r\n infoLabel: {\r\n display: \"flex\",\r\n flex: \"1 1 0\", // grow=1, shrink =1, basis = 0 initial size before\r\n minWidth: CustomTokens.labelMinWidth,\r\n textAlign: \"left\",\r\n },\r\n rightContent: {\r\n flex: \"0 1 auto\",\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-end\",\r\n },\r\n childWrapper: {\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n infoPopup: {\r\n whiteSpace: \"normal\",\r\n wordBreak: \"break-word\",\r\n },\r\n copy: {\r\n marginRight: CustomTokens.rightAlignOffset, // Accounts for the padding baked into fluent button / ensures propertyLine looks visually aligned at the right\r\n },\r\n expandedContentDiv: {\r\n overflow: \"hidden\",\r\n },\r\n checkbox: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n marginRight: tokens.spacingHorizontalXS,\r\n },\r\n checkboxIndicator: {\r\n margin: TokenMap.px2,\r\n width: TokenMap.px12,\r\n height: TokenMap.px12,\r\n },\r\n});\r\n\r\ntype BasePropertyLineProps = {\r\n /**\r\n * The name of the property to display in the property line.\r\n */\r\n label: string;\r\n /**\r\n * Optional description for the property, shown on hover of the info icon\r\n */\r\n description?: string;\r\n /**\r\n * Optional function returning a string to copy to clipboard.\r\n */\r\n onCopy?: () => string;\r\n /**\r\n * Link to the documentation for this property, available from the info icon either linked from the description (if provided) or default 'docs' text\r\n */\r\n docLink?: string;\r\n};\r\n\r\n// Only require value/onChange/defaultValue props if nullable is true\r\ntype NullableProperty<ValueT> = {\r\n nullable: true;\r\n ignoreNullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue?: ValueT;\r\n};\r\n\r\ntype IgnoreNullable<ValueT> = {\r\n ignoreNullable: true;\r\n nullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue: ValueT;\r\n};\r\n\r\ntype NonNullableProperty = {\r\n nullable?: false;\r\n ignoreNullable?: false;\r\n};\r\n\r\n// Only expect optional expandByDefault prop if expandedContent is defined\r\ntype ExpandableProperty = {\r\n /**\r\n * If supplied, an 'expand' icon will be shown which, when clicked, renders this component within the property line.\r\n */\r\n expandedContent: JSX.Element;\r\n\r\n /**\r\n * If true, the expanded content will be shown by default.\r\n */\r\n expandByDefault?: boolean;\r\n};\r\n\r\n// If expanded content is undefined, don't expect expandByDefault prop\r\ntype NonExpandableProperty = {\r\n expandedContent?: undefined;\r\n};\r\n\r\nexport type PropertyLineProps<ValueT> = BasePropertyLineProps &\r\n (NullableProperty<ValueT> | NonNullableProperty | IgnoreNullable<ValueT>) &\r\n (ExpandableProperty | NonExpandableProperty);\r\n\r\n/**\r\n * A reusable component that renders a property line with a label and child content, and an optional description, copy button, and expandable section.\r\n *\r\n * @param props - The properties for the PropertyLine component.\r\n * @returns A React element representing the property line.\r\n *\r\n */\r\nexport const PropertyLine = forwardRef<HTMLDivElement, PropsWithChildren<PropertyLineProps<any>>>((props, ref) => {\r\n PropertyLine.displayName = \"PropertyLine\";\r\n const { disableCopy, size } = useContext(ToolContext);\r\n const classes = usePropertyLineStyles();\r\n const { label, onCopy, expandedContent, children, nullable, ignoreNullable } = props;\r\n\r\n const [expanded, setExpanded] = useState(\"expandByDefault\" in props ? props.expandByDefault : false);\r\n const cachedVal = useRef(nullable ? props.value : null);\r\n\r\n const description = props.docLink ? <Link url={props.docLink} value={props.description ?? \"Docs\"} /> : props.description ? <Body1>{props.description}</Body1> : undefined;\r\n\r\n // Process children to handle nullable state -- creating component in disabled state with default value in lieu of null value\r\n const processedChildren =\r\n (nullable || ignoreNullable) && isValidElement(children)\r\n ? cloneElement(children, {\r\n ...children.props,\r\n disabled: children.props.disabled || (nullable && props.value == null),\r\n value: props.value ?? props.defaultValue,\r\n defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state\r\n })\r\n : children;\r\n\r\n return (\r\n <LineContainer ref={ref}>\r\n <div className={classes.baseLine}>\r\n <InfoLabel className={classes.infoLabel} htmlFor=\"property\" info={description} label={label} flexLabel />\r\n <div className={classes.rightContent} id=\"property\">\r\n {expandedContent && (\r\n <ToggleButton\r\n title=\"Expand/Collapse property\"\r\n appearance=\"transparent\"\r\n checkedIcon={size === \"small\" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular}\r\n uncheckedIcon={size === \"small\" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular}\r\n value={expanded === true}\r\n onChange={setExpanded}\r\n />\r\n )}\r\n\r\n {nullable && !ignoreNullable && (\r\n // If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')\r\n <Tooltip relationship=\"label\" content={props.value == null ? \"Enable property\" : \"Disable property (set to null)\"}>\r\n <Checkbox\r\n className={classes.checkbox}\r\n indicator={{ className: classes.checkboxIndicator }}\r\n checked={!(props.value == null)}\r\n onChange={(_, data) => {\r\n if (data.checked) {\r\n // if checked this means we are returning to non-null, use cached value if exists. If no cached value, use default value\r\n cachedVal.current != null ? props.onChange(cachedVal.current) : props.onChange(props.defaultValue);\r\n } else {\r\n // if moving to un-checked state, this means moving to null value. Cache the old value and tell props.onChange(null)\r\n cachedVal.current = props.value;\r\n props.onChange(null);\r\n }\r\n }}\r\n />\r\n </Tooltip>\r\n )}\r\n <div className={classes.childWrapper}>{processedChildren}</div>\r\n {onCopy && !disableCopy && (\r\n <Button\r\n className={classes.copy}\r\n title=\"Copy to clipboard\"\r\n appearance=\"transparent\"\r\n icon={size === \"small\" ? Copy16Regular : CopyRegular}\r\n onClick={() => copyCommandToClipboard(onCopy())}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n {expandedContent && (\r\n <Collapse visible={!!expanded}>\r\n <div className={classes.expandedContentDiv}>{expandedContent}</div>\r\n </Collapse>\r\n )}\r\n </LineContainer>\r\n );\r\n});\r\n\r\nconst useLineStyles = makeStyles({\r\n container: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\", // Stack line + expanded content\r\n minHeight: CustomTokens.lineHeight,\r\n boxSizing: \"border-box\",\r\n justifyContent: \"center\",\r\n paddingTop: tokens.spacingVerticalXXS,\r\n paddingBottom: tokens.spacingVerticalXXS,\r\n borderTop: `1px solid transparent`,\r\n borderBottom: `1px solid transparent`,\r\n \":hover\": {\r\n borderTopColor: tokens.colorNeutralStroke2,\r\n borderBottomColor: tokens.colorNeutralStroke2,\r\n },\r\n },\r\n containerSmall: {\r\n minHeight: CustomTokens.lineHeightSmall,\r\n },\r\n});\r\n\r\nexport const LineContainer = forwardRef<HTMLDivElement, PropsWithChildren<HTMLProps<HTMLDivElement>>>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const classes = useLineStyles();\r\n\r\n return (\r\n <div ref={ref} className={mergeClasses(classes.container, size == \"small\" ? classes.containerSmall : undefined)} {...props}>\r\n {props.children}\r\n </div>\r\n );\r\n});\r\n\r\nexport const PlaceholderPropertyLine: FunctionComponent<PrimitiveProps<any> & PropertyLineProps<any>> = (props) => {\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1>{props.value}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
@@ -30,7 +30,7 @@ const TensorPropertyLine = (props) => {
30
30
  useEffect(() => {
31
31
  setVector(props.value);
32
32
  }, [props.value, props.expandedContent]);
33
- return (_jsx(PropertyLine, { ...props, onCopy: () => `new ${props.value.getClassName()}(${vector.x},${vector.y}${HasZ(vector) ? `,${vector.z}` : ""}${HasW(vector) ? `,${vector.w}` : ""})`, expandedContent: vector ? _jsx(VectorSliders, { vector: vector, min: min, max: max, unit: props.unit, step: props.step, converted: converted, onChange: onChange }) : undefined, children: _jsx(Body1, { children: `[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : ""}${HasW(props.value) ? `, ${formatted(props.value.w)}` : ""}]` }) }));
33
+ return (_jsx(PropertyLine, { ...props, expandedContent: vector ? _jsx(VectorSliders, { vector: vector, min: min, max: max, unit: props.unit, step: props.step, converted: converted, onChange: onChange }) : undefined, children: _jsx(Body1, { children: `[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : ""}${HasW(props.value) ? `, ${formatted(props.value.w)}` : ""}]` }) }));
34
34
  };
35
35
  const VectorSliders = ({ vector, min, max, unit, step, converted, onChange }) => (_jsxs(_Fragment, { children: [_jsx(SyncedSliderPropertyLine, { label: "X", value: converted(vector.x), min: min, max: max, onChange: (val) => onChange(val, "x"), unit: unit, step: step }), _jsx(SyncedSliderPropertyLine, { label: "Y", value: converted(vector.y), min: min, max: max, onChange: (val) => onChange(val, "y"), unit: unit, step: step }), HasZ(vector) && _jsx(SyncedSliderPropertyLine, { label: "Z", value: converted(vector.z), min: min, max: max, onChange: (val) => onChange(val, "z"), unit: unit, step: step }), HasW(vector) && _jsx(SyncedSliderPropertyLine, { label: "W", value: converted(vector.w), min: min, max: max, onChange: (val) => onChange(val, "w"), unit: unit, step: step })] }));
36
36
  const ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };
@@ -1 +1 @@
1
- {"version":3,"file":"vectorPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/vectorPropertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\n\r\nimport { Body1 } from \"@fluentui/react-components\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\n\r\nimport { SyncedSliderPropertyLine } from \"./syncedSliderPropertyLine\";\r\nimport type { Vector3 } from \"core/Maths/math.vector\";\r\nimport { Quaternion, Vector2, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { CalculatePrecision } from \"../../primitives/utils\";\r\n\r\nexport type TensorPropertyLineProps<V extends Vector2 | Vector3 | Vector4 | Quaternion> = PropertyLineProps<V> &\r\n PrimitiveProps<V> & {\r\n /**\r\n * If passed, all sliders will use this for the min value\r\n */\r\n min?: number;\r\n /**\r\n * If passed, all sliders will use this for the max value\r\n */\r\n max?: number;\r\n /**\r\n * Will be displayed in the input UI to indicate the unit of measurement\r\n */\r\n unit?: string;\r\n\r\n /**\r\n * Internal spinbutton's step\r\n */\r\n step?: number;\r\n /**\r\n * If passed, the UX will use the conversion functions to display/update values\r\n */\r\n valueConverter?: {\r\n /**\r\n * Will call from(val) before displaying in the UX\r\n */\r\n from: (val: number) => number;\r\n /**\r\n * Will call to(val) before calling onChange\r\n */\r\n to: (val: number) => number;\r\n };\r\n };\r\n\r\nconst HasZ = (vector: Vector2 | Vector3 | Vector4 | Quaternion): vector is Vector3 => !(vector instanceof Vector2);\r\nconst HasW = (vector: Vector2 | Vector3 | Vector4 | Quaternion): vector is Vector4 => vector instanceof Vector4 || vector instanceof Quaternion;\r\n\r\n/**\r\n * Reusable component which renders a vector property line containing a label, vector value, and expandable XYZW values\r\n * The expanded section contains a slider/input box for each component of the vector (x, y, z, w)\r\n * @param props\r\n * @returns\r\n */\r\nconst TensorPropertyLine: FunctionComponent<TensorPropertyLineProps<Vector2 | Vector3 | Vector4 | Quaternion>> = (props) => {\r\n TensorPropertyLine.displayName = \"TensorPropertyLine\";\r\n const converted = (val: number) => (props.valueConverter ? props.valueConverter.from(val) : val);\r\n const formatted = (val: number) => converted(val).toFixed(props.step !== undefined ? Math.max(0, CalculatePrecision(props.step)) : 2);\r\n\r\n const [vector, setVector] = useState(props.value);\r\n const { min, max } = props;\r\n\r\n const onChange = (val: number, key: \"x\" | \"y\" | \"z\" | \"w\") => {\r\n const value = props.valueConverter ? props.valueConverter.to(val) : val;\r\n const newVector = vector.clone();\r\n (newVector as Vector4)[key] = value; // The syncedSlider for 'w' is only rendered when vector is a Vector4, so this is safe\r\n\r\n setVector(newVector);\r\n props.onChange(newVector);\r\n };\r\n\r\n useEffect(() => {\r\n setVector(props.value);\r\n }, [props.value, props.expandedContent]);\r\n\r\n return (\r\n <PropertyLine\r\n {...props}\r\n onCopy={() => `new ${props.value.getClassName()}(${vector.x},${vector.y}${HasZ(vector) ? `,${vector.z}` : \"\"}${HasW(vector) ? `,${vector.w}` : \"\"})`}\r\n expandedContent={\r\n vector ? <VectorSliders vector={vector} min={min} max={max} unit={props.unit} step={props.step} converted={converted} onChange={onChange} /> : undefined\r\n }\r\n >\r\n <Body1>{`[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : \"\"}${HasW(props.value) ? `, ${formatted(props.value.w)}` : \"\"}]`}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n\r\ntype VectorSlidersProps<V extends Vector2 | Vector3 | Vector4 | Quaternion> = {\r\n vector: V;\r\n min?: number;\r\n max?: number;\r\n unit?: string;\r\n step?: number;\r\n converted: (val: number) => number;\r\n onChange: (val: number, key: \"x\" | \"y\" | \"z\" | \"w\") => void;\r\n};\r\n\r\nconst VectorSliders = <V extends Vector2 | Vector3 | Vector4 | Quaternion>({ vector, min, max, unit, step, converted, onChange }: VectorSlidersProps<V>) => (\r\n <>\r\n <SyncedSliderPropertyLine label=\"X\" value={converted(vector.x)} min={min} max={max} onChange={(val) => onChange(val, \"x\")} unit={unit} step={step} />\r\n <SyncedSliderPropertyLine label=\"Y\" value={converted(vector.y)} min={min} max={max} onChange={(val) => onChange(val, \"y\")} unit={unit} step={step} />\r\n {HasZ(vector) && <SyncedSliderPropertyLine label=\"Z\" value={converted(vector.z)} min={min} max={max} onChange={(val) => onChange(val, \"z\")} unit={unit} step={step} />}\r\n {HasW(vector) && <SyncedSliderPropertyLine label=\"W\" value={converted(vector.w)} min={min} max={max} onChange={(val) => onChange(val, \"w\")} unit={unit} step={step} />}\r\n </>\r\n);\r\n\r\ntype RotationVectorPropertyLineProps = TensorPropertyLineProps<Vector3> & {\r\n /**\r\n * Display angles as degrees instead of radians\r\n */\r\n useDegrees?: boolean;\r\n};\r\n\r\nconst ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };\r\nexport const RotationVectorPropertyLine: FunctionComponent<RotationVectorPropertyLineProps> = (props) => {\r\n RotationVectorPropertyLine.displayName = \"RotationVectorPropertyLine\";\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n return (\r\n <Vector3PropertyLine\r\n {...props}\r\n unit={props.useDegrees ? \"deg\" : \"rad\"}\r\n valueConverter={props.useDegrees ? ToDegreesConverter : undefined}\r\n min={min}\r\n max={max}\r\n step={0.001}\r\n />\r\n );\r\n};\r\n\r\ntype QuaternionPropertyLineProps = TensorPropertyLineProps<Quaternion> & {\r\n /**\r\n * Display angles as degrees instead of radians\r\n */\r\n useDegrees?: boolean;\r\n /**\r\n * Display angles as Euler angles instead of quaternions\r\n */\r\n useEuler?: boolean;\r\n};\r\nconst QuaternionPropertyLineInternal = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Quaternion>>;\r\nexport const QuaternionPropertyLine: FunctionComponent<QuaternionPropertyLineProps> = (props) => {\r\n QuaternionPropertyLine.displayName = \"QuaternionPropertyLine\";\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n const [quat, setQuat] = useState(props.value);\r\n\r\n useEffect(() => {\r\n setQuat(props.value);\r\n }, [props.value]);\r\n\r\n // Extract only the properties that exist on QuaternionPropertyLineProps\r\n const { useEuler, ...restProps } = props;\r\n\r\n const onQuatChange = (val: Quaternion) => {\r\n setQuat(val);\r\n props.onChange(val);\r\n };\r\n\r\n const onEulerChange = (val: Vector3) => {\r\n const quat = Quaternion.FromEulerAngles(val.x, val.y, val.z);\r\n onQuatChange(quat);\r\n };\r\n\r\n return useEuler ? (\r\n <Vector3PropertyLine\r\n {...restProps}\r\n nullable={false}\r\n ignoreNullable={false}\r\n value={quat.toEulerAngles()}\r\n valueConverter={ToDegreesConverter}\r\n min={min}\r\n max={max}\r\n onChange={onEulerChange}\r\n unit={props.useDegrees ? \"deg\" : \"rad\"}\r\n />\r\n ) : (\r\n <QuaternionPropertyLineInternal {...props} nullable={false} value={quat} min={min} max={max} onChange={onQuatChange} unit={props.useDegrees ? \"deg\" : \"rad\"} />\r\n );\r\n};\r\nexport const Vector2PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector2>>;\r\nexport const Vector3PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector3>>;\r\nexport const Vector4PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector4>>;\r\n"]}
1
+ {"version":3,"file":"vectorPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/vectorPropertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\n\r\nimport { Body1 } from \"@fluentui/react-components\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\n\r\nimport { SyncedSliderPropertyLine } from \"./syncedSliderPropertyLine\";\r\nimport type { Vector3 } from \"core/Maths/math.vector\";\r\nimport { Quaternion, Vector2, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { CalculatePrecision } from \"../../primitives/utils\";\r\n\r\nexport type TensorPropertyLineProps<V extends Vector2 | Vector3 | Vector4 | Quaternion> = PropertyLineProps<V> &\r\n PrimitiveProps<V> & {\r\n /**\r\n * If passed, all sliders will use this for the min value\r\n */\r\n min?: number;\r\n /**\r\n * If passed, all sliders will use this for the max value\r\n */\r\n max?: number;\r\n /**\r\n * Will be displayed in the input UI to indicate the unit of measurement\r\n */\r\n unit?: string;\r\n\r\n /**\r\n * Internal spinbutton's step\r\n */\r\n step?: number;\r\n /**\r\n * If passed, the UX will use the conversion functions to display/update values\r\n */\r\n valueConverter?: {\r\n /**\r\n * Will call from(val) before displaying in the UX\r\n */\r\n from: (val: number) => number;\r\n /**\r\n * Will call to(val) before calling onChange\r\n */\r\n to: (val: number) => number;\r\n };\r\n };\r\n\r\nconst HasZ = (vector: Vector2 | Vector3 | Vector4 | Quaternion): vector is Vector3 => !(vector instanceof Vector2);\r\nconst HasW = (vector: Vector2 | Vector3 | Vector4 | Quaternion): vector is Vector4 => vector instanceof Vector4 || vector instanceof Quaternion;\r\n\r\n/**\r\n * Reusable component which renders a vector property line containing a label, vector value, and expandable XYZW values\r\n * The expanded section contains a slider/input box for each component of the vector (x, y, z, w)\r\n * @param props\r\n * @returns\r\n */\r\nconst TensorPropertyLine: FunctionComponent<TensorPropertyLineProps<Vector2 | Vector3 | Vector4 | Quaternion>> = (props) => {\r\n TensorPropertyLine.displayName = \"TensorPropertyLine\";\r\n const converted = (val: number) => (props.valueConverter ? props.valueConverter.from(val) : val);\r\n const formatted = (val: number) => converted(val).toFixed(props.step !== undefined ? Math.max(0, CalculatePrecision(props.step)) : 2);\r\n\r\n const [vector, setVector] = useState(props.value);\r\n const { min, max } = props;\r\n\r\n const onChange = (val: number, key: \"x\" | \"y\" | \"z\" | \"w\") => {\r\n const value = props.valueConverter ? props.valueConverter.to(val) : val;\r\n const newVector = vector.clone();\r\n (newVector as Vector4)[key] = value; // The syncedSlider for 'w' is only rendered when vector is a Vector4, so this is safe\r\n\r\n setVector(newVector);\r\n props.onChange(newVector);\r\n };\r\n\r\n useEffect(() => {\r\n setVector(props.value);\r\n }, [props.value, props.expandedContent]);\r\n\r\n return (\r\n <PropertyLine\r\n {...props}\r\n expandedContent={\r\n vector ? <VectorSliders vector={vector} min={min} max={max} unit={props.unit} step={props.step} converted={converted} onChange={onChange} /> : undefined\r\n }\r\n >\r\n <Body1>{`[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : \"\"}${HasW(props.value) ? `, ${formatted(props.value.w)}` : \"\"}]`}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n\r\ntype VectorSlidersProps<V extends Vector2 | Vector3 | Vector4 | Quaternion> = {\r\n vector: V;\r\n min?: number;\r\n max?: number;\r\n unit?: string;\r\n step?: number;\r\n converted: (val: number) => number;\r\n onChange: (val: number, key: \"x\" | \"y\" | \"z\" | \"w\") => void;\r\n};\r\n\r\nconst VectorSliders = <V extends Vector2 | Vector3 | Vector4 | Quaternion>({ vector, min, max, unit, step, converted, onChange }: VectorSlidersProps<V>) => (\r\n <>\r\n <SyncedSliderPropertyLine label=\"X\" value={converted(vector.x)} min={min} max={max} onChange={(val) => onChange(val, \"x\")} unit={unit} step={step} />\r\n <SyncedSliderPropertyLine label=\"Y\" value={converted(vector.y)} min={min} max={max} onChange={(val) => onChange(val, \"y\")} unit={unit} step={step} />\r\n {HasZ(vector) && <SyncedSliderPropertyLine label=\"Z\" value={converted(vector.z)} min={min} max={max} onChange={(val) => onChange(val, \"z\")} unit={unit} step={step} />}\r\n {HasW(vector) && <SyncedSliderPropertyLine label=\"W\" value={converted(vector.w)} min={min} max={max} onChange={(val) => onChange(val, \"w\")} unit={unit} step={step} />}\r\n </>\r\n);\r\n\r\ntype RotationVectorPropertyLineProps = TensorPropertyLineProps<Vector3> & {\r\n /**\r\n * Display angles as degrees instead of radians\r\n */\r\n useDegrees?: boolean;\r\n};\r\n\r\nconst ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };\r\nexport const RotationVectorPropertyLine: FunctionComponent<RotationVectorPropertyLineProps> = (props) => {\r\n RotationVectorPropertyLine.displayName = \"RotationVectorPropertyLine\";\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n return (\r\n <Vector3PropertyLine\r\n {...props}\r\n unit={props.useDegrees ? \"deg\" : \"rad\"}\r\n valueConverter={props.useDegrees ? ToDegreesConverter : undefined}\r\n min={min}\r\n max={max}\r\n step={0.001}\r\n />\r\n );\r\n};\r\n\r\ntype QuaternionPropertyLineProps = TensorPropertyLineProps<Quaternion> & {\r\n /**\r\n * Display angles as degrees instead of radians\r\n */\r\n useDegrees?: boolean;\r\n /**\r\n * Display angles as Euler angles instead of quaternions\r\n */\r\n useEuler?: boolean;\r\n};\r\nconst QuaternionPropertyLineInternal = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Quaternion>>;\r\nexport const QuaternionPropertyLine: FunctionComponent<QuaternionPropertyLineProps> = (props) => {\r\n QuaternionPropertyLine.displayName = \"QuaternionPropertyLine\";\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n const [quat, setQuat] = useState(props.value);\r\n\r\n useEffect(() => {\r\n setQuat(props.value);\r\n }, [props.value]);\r\n\r\n // Extract only the properties that exist on QuaternionPropertyLineProps\r\n const { useEuler, ...restProps } = props;\r\n\r\n const onQuatChange = (val: Quaternion) => {\r\n setQuat(val);\r\n props.onChange(val);\r\n };\r\n\r\n const onEulerChange = (val: Vector3) => {\r\n const quat = Quaternion.FromEulerAngles(val.x, val.y, val.z);\r\n onQuatChange(quat);\r\n };\r\n\r\n return useEuler ? (\r\n <Vector3PropertyLine\r\n {...restProps}\r\n nullable={false}\r\n ignoreNullable={false}\r\n value={quat.toEulerAngles()}\r\n valueConverter={ToDegreesConverter}\r\n min={min}\r\n max={max}\r\n onChange={onEulerChange}\r\n unit={props.useDegrees ? \"deg\" : \"rad\"}\r\n />\r\n ) : (\r\n <QuaternionPropertyLineInternal {...props} nullable={false} value={quat} min={min} max={max} onChange={onQuatChange} unit={props.useDegrees ? \"deg\" : \"rad\"} />\r\n );\r\n};\r\nexport const Vector2PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector2>>;\r\nexport const Vector3PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector3>>;\r\nexport const Vector4PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector4>>;\r\n"]}
@@ -1,14 +1,24 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Button as FluentButton, Spinner } from "@fluentui/react-components";
2
+ import { Button as FluentButton, makeStyles, Spinner } from "@fluentui/react-components";
3
3
  import { forwardRef, useCallback, useContext, useState } from "react";
4
4
  import { ToolContext } from "../hoc/fluentToolWrapper.js";
5
+ import { TokenMap } from "./utils.js";
6
+ const useButtonStyles = makeStyles({
7
+ smallIcon: {
8
+ fontSize: TokenMap.px16,
9
+ },
10
+ mediumIcon: {
11
+ fontSize: TokenMap.px20,
12
+ },
13
+ });
5
14
  export const Button = forwardRef((props, ref) => {
6
15
  const { size } = useContext(ToolContext);
16
+ const classes = useButtonStyles();
7
17
  // eslint-disable-next-line @typescript-eslint/naming-convention
8
- const { icon: Icon, label, onClick, disabled, ...buttonProps } = props;
18
+ const { icon: Icon, label, onClick, disabled, className, ...buttonProps } = props;
9
19
  const [isOnClickBusy, setIsOnClickBusy] = useState(false);
10
20
  const handleOnClick = useCallback(async (e) => {
11
- const result = onClick?.();
21
+ const result = onClick?.(e);
12
22
  if (result instanceof Promise) {
13
23
  setIsOnClickBusy(true);
14
24
  try {
@@ -19,7 +29,8 @@ export const Button = forwardRef((props, ref) => {
19
29
  }
20
30
  }
21
31
  }, [onClick]);
22
- return (_jsx(FluentButton, { ref: ref, iconPosition: "after", ...buttonProps, size: size, icon: isOnClickBusy ? _jsx(Spinner, { size: "extra-tiny" }) : Icon && _jsx(Icon, {}), onClick: handleOnClick, disabled: disabled || isOnClickBusy, children: label && props.label }));
32
+ const iconClass = size === "small" ? classes.smallIcon : classes.mediumIcon;
33
+ return (_jsx(FluentButton, { ref: ref, iconPosition: "after", ...buttonProps, className: className, size: size, icon: isOnClickBusy ? _jsx(Spinner, { size: "extra-tiny" }) : Icon && _jsx(Icon, { className: iconClass }), onClick: handleOnClick, disabled: disabled || isOnClickBusy, children: label && props.label }));
23
34
  });
24
35
  Button.displayName = "Button";
25
36
  //# sourceMappingURL=button.js.map
@@ -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,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AASvD,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,gEAAgE;IAChE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,WAAW,EAAE,GAAG,KAAK,CAAC;IAEvE,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,EAAE,CAAC;QAC3B,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,OAAO,CACH,KAAC,YAAY,IACT,GAAG,EAAE,GAAG,EACR,YAAY,EAAC,OAAO,KAChB,WAAW,EACf,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,IAAI,EAAC,YAAY,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,KAAC,IAAI,KAAG,EACtE,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, 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\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 // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const { icon: Icon, label, onClick, disabled, ...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?.();\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 return (\r\n <FluentButton\r\n ref={ref}\r\n iconPosition=\"after\"\r\n {...buttonProps}\r\n size={size}\r\n icon={isOnClickBusy ? <Spinner size=\"extra-tiny\" /> : Icon && <Icon />}\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\";\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"]}
@@ -10,22 +10,24 @@ const useGradientStyles = makeStyles({
10
10
  container: {
11
11
  display: "flex",
12
12
  alignItems: "center",
13
- gap: tokens.spacingHorizontalS,
13
+ gap: tokens.spacingHorizontalXS, // Reduced gap
14
14
  width: "100%",
15
+ minWidth: 0,
16
+ overflow: "hidden",
15
17
  },
16
- // Wrapper for factor spin buttons - fixed size
18
+ // Wrapper for factor spin buttons - fixed width, doesn't grow
17
19
  valueWrapper: {
18
- flex: "0 0 auto", // Don't grow, natural size
20
+ flex: "0 0 auto", // Fixed size, no grow, no shrink
19
21
  },
20
22
  // Wrapper for color pickers - fixed size since they're just swatches
21
23
  colorWrapper: {
22
24
  flex: "0 0 auto",
23
25
  alignContent: "center",
24
26
  },
25
- // Wrapper for the step slider - grows to fill remaining space
27
+ // Wrapper for the step slider - takes remaining space and can shrink
26
28
  stepSliderWrapper: {
27
29
  flex: "1 1 0", // Grow to fill available space
28
- minWidth: 0,
30
+ minWidth: "100px", // Minimum to fit slider + spinbutton
29
31
  },
30
32
  });
31
33
  /**
@@ -47,7 +49,7 @@ const Gradient = (props) => {
47
49
  // Only use compact mode when there are numeric values (spinbuttons) taking up space
48
50
  const hasNumericValues = !(gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4) ||
49
51
  (gradient.value2 !== undefined && !(gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4));
50
- return (_jsxs("div", { id: "gradientContainer", className: classes.container, children: [_jsx("div", { className: gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4 ? classes.colorWrapper : classes.valueWrapper, children: gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4 ? (_jsx(ColorPickerPopup, { value: gradient.value1, onChange: (color) => gradientChange({ ...gradient, value1: color }) })) : (_jsx(SyncedSliderInput, { step: 0.01, value: gradient.value1, onChange: (val) => gradientChange({ ...gradient, value1: val }), compact: true })) }), gradient.value2 !== undefined && (_jsx("div", { className: gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4 ? classes.colorWrapper : classes.valueWrapper, children: gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4 ? (_jsx(ColorPickerPopup, { value: gradient.value2, onChange: (color) => gradientChange({ ...gradient, value2: color }) })) : (_jsx(SyncedSliderInput, { step: 0.01, value: gradient.value2, onChange: (val) => gradientChange({ ...gradient, value2: val }), compact: true })) })), _jsx("div", { className: classes.stepSliderWrapper, children: _jsx(SyncedSliderInput, { notifyOnlyOnRelease: true, min: 0, max: 1, step: 0.01, value: gradient.step, onChange: (val) => gradientChange({ ...gradient, step: val }), compact: hasNumericValues }) })] }));
52
+ return (_jsxs("div", { id: "gradientContainer", className: classes.container, children: [_jsx("div", { className: gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4 ? classes.colorWrapper : classes.valueWrapper, children: gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4 ? (_jsx(ColorPickerPopup, { value: gradient.value1, onChange: (color) => gradientChange({ ...gradient, value1: color }) })) : (_jsx(SyncedSliderInput, { step: 0.01, value: gradient.value1, onChange: (val) => gradientChange({ ...gradient, value1: val }), compact: true })) }), gradient.value2 !== undefined && (_jsx("div", { className: gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4 ? classes.colorWrapper : classes.valueWrapper, children: gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4 ? (_jsx(ColorPickerPopup, { value: gradient.value2, onChange: (color) => gradientChange({ ...gradient, value2: color }) })) : (_jsx(SyncedSliderInput, { step: 0.01, value: gradient.value2, onChange: (val) => gradientChange({ ...gradient, value2: val }), compact: true })) })), _jsx("div", { className: classes.stepSliderWrapper, children: _jsx(SyncedSliderInput, { notifyOnlyOnRelease: true, min: 0, max: 1, step: 0.01, value: gradient.step, onChange: (val) => gradientChange({ ...gradient, step: val }), compact: hasNumericValues, growSlider: !hasNumericValues }) })] }));
51
53
  };
52
54
  const FactorGradientCast = Gradient;
53
55
  const Color3GradientCast = Gradient;
@@ -1 +1 @@
1
- {"version":3,"file":"gradient.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/gradient.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { FunctionComponent } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { useEffect, useState } from \"react\";\r\nimport { makeStyles, tokens } from \"@fluentui/react-components\";\r\n\r\nimport { SyncedSliderInput } from \"./syncedSlider\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\nimport { ColorPickerPopup } from \"./colorPicker\";\r\nimport { Color3Gradient, ColorGradient as Color4Gradient, FactorGradient } from \"core/Misc/gradients\";\r\nimport { GradientBlockColorStep } from \"core/Materials/Node/Blocks/gradientBlock\";\r\n\r\nconst useGradientStyles = makeStyles({\r\n container: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: tokens.spacingHorizontalS,\r\n width: \"100%\",\r\n },\r\n // Wrapper for factor spin buttons - fixed size\r\n valueWrapper: {\r\n flex: \"0 0 auto\", // Don't grow, natural size\r\n },\r\n // Wrapper for color pickers - fixed size since they're just swatches\r\n colorWrapper: {\r\n flex: \"0 0 auto\",\r\n alignContent: \"center\",\r\n },\r\n // Wrapper for the step slider - grows to fill remaining space\r\n stepSliderWrapper: {\r\n flex: \"1 1 0\", // Grow to fill available space\r\n minWidth: 0,\r\n },\r\n});\r\n\r\ntype GradientProps<T extends number | Color3 | Color4> = {\r\n value1: T;\r\n value2?: T;\r\n step: number;\r\n};\r\n\r\n/**\r\n * Gradient component that displays 1 or 2 color or number inputs next to a slider\r\n * @param props - Component props containing gradient value and change handlers\r\n * @returns A React component\r\n */\r\nconst Gradient: FunctionComponent<PrimitiveProps<GradientProps<number | Color3 | Color4>>> = (props) => {\r\n Gradient.displayName = \"Gradient\";\r\n const [gradient, setGradient] = useState(props.value);\r\n const classes = useGradientStyles();\r\n\r\n useEffect(() => {\r\n setGradient(props.value); // Re-render if props.value changes\r\n }, [props.value]);\r\n\r\n const gradientChange = (newGradient: GradientProps<number | Color3 | Color4>) => {\r\n setGradient(newGradient);\r\n props.onChange(newGradient);\r\n };\r\n // Only use compact mode when there are numeric values (spinbuttons) taking up space\r\n const hasNumericValues =\r\n !(gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4) ||\r\n (gradient.value2 !== undefined && !(gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4));\r\n\r\n return (\r\n <div id=\"gradientContainer\" className={classes.container}>\r\n <div className={gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4 ? classes.colorWrapper : classes.valueWrapper}>\r\n {gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4 ? (\r\n <ColorPickerPopup value={gradient.value1} onChange={(color) => gradientChange({ ...gradient, value1: color })} />\r\n ) : (\r\n <SyncedSliderInput step={0.01} value={gradient.value1} onChange={(val) => gradientChange({ ...gradient, value1: val })} compact />\r\n )}\r\n </div>\r\n {gradient.value2 !== undefined && (\r\n <div className={gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4 ? classes.colorWrapper : classes.valueWrapper}>\r\n {gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4 ? (\r\n <ColorPickerPopup value={gradient.value2} onChange={(color) => gradientChange({ ...gradient, value2: color })} />\r\n ) : (\r\n <SyncedSliderInput step={0.01} value={gradient.value2} onChange={(val) => gradientChange({ ...gradient, value2: val })} compact />\r\n )}\r\n </div>\r\n )}\r\n\r\n <div className={classes.stepSliderWrapper}>\r\n <SyncedSliderInput\r\n notifyOnlyOnRelease={true}\r\n min={0}\r\n max={1}\r\n step={0.01}\r\n value={gradient.step}\r\n onChange={(val) => gradientChange({ ...gradient, step: val })}\r\n compact={hasNumericValues}\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nconst FactorGradientCast = Gradient as FunctionComponent<PrimitiveProps<GradientProps<number>>>;\r\nconst Color3GradientCast = Gradient as FunctionComponent<PrimitiveProps<GradientProps<Color3>>>;\r\nconst Color4GradientCast = Gradient as FunctionComponent<PrimitiveProps<GradientProps<Color4>>>;\r\n\r\n/**\r\n * Component wrapper for FactorGradient that provides slider inputs for factor1, factor2, and gradient step\r\n * @param props - Component props containing FactorGradient value and change handler\r\n * @returns A React component\r\n */\r\nexport const FactorGradientComponent: FunctionComponent<PrimitiveProps<FactorGradient>> = (props) => {\r\n return (\r\n <FactorGradientCast\r\n {...props}\r\n value={{ value1: props.value.factor1, value2: props.value.factor2, step: props.value.gradient }}\r\n onChange={(gradient) => props.onChange(new FactorGradient(gradient.step, gradient.value1, gradient.value2))}\r\n />\r\n );\r\n};\r\n/**\r\n * Component wrapper for Color3Gradient that provides color picker and gradient step slider\r\n * @param props - Component props containing Color3Gradient value and change handler\r\n * @returns A React component\r\n */\r\nexport const Color3GradientComponent: FunctionComponent<PrimitiveProps<Color3Gradient>> = (props) => {\r\n return (\r\n <Color3GradientCast\r\n {...props}\r\n value={{ value1: props.value.color, step: props.value.gradient }}\r\n onChange={(gradient) => props.onChange(new Color3Gradient(gradient.step, gradient.value1))}\r\n />\r\n );\r\n};\r\n/**\r\n * Component wrapper for Color4Gradient that provides color pickers for color1, color2, and gradient step slider\r\n * @param props - Component props containing Color4Gradient value and change handler\r\n * @returns A React component\r\n */\r\nexport const Color4GradientComponent: FunctionComponent<PrimitiveProps<Color4Gradient>> = (props) => {\r\n return (\r\n <Color4GradientCast\r\n {...props}\r\n value={{ value1: props.value.color1, value2: props.value.color2, step: props.value.gradient }}\r\n onChange={(gradient) => props.onChange(new Color4Gradient(gradient.step, gradient.value1, gradient.value2))}\r\n />\r\n );\r\n};\r\n/**\r\n * Component wrapper for GradientBlockColorStep that provides color picker and step slider\r\n * @param props - Component props containing GradientBlockColorStep value and change handler\r\n * @returns A React component\r\n */\r\nexport const ColorStepGradientComponent: FunctionComponent<PrimitiveProps<GradientBlockColorStep>> = (props) => {\r\n return (\r\n <Color3GradientCast\r\n {...props}\r\n value={{ value1: props.value.color, step: props.value.step }}\r\n onChange={(gradient) => props.onChange(new GradientBlockColorStep(gradient.step, gradient.value1))}\r\n />\r\n );\r\n};\r\n"]}
1
+ {"version":3,"file":"gradient.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/gradient.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { FunctionComponent } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { useEffect, useState } from \"react\";\r\nimport { makeStyles, tokens } from \"@fluentui/react-components\";\r\n\r\nimport { SyncedSliderInput } from \"./syncedSlider\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\nimport { ColorPickerPopup } from \"./colorPicker\";\r\nimport { Color3Gradient, ColorGradient as Color4Gradient, FactorGradient } from \"core/Misc/gradients\";\r\nimport { GradientBlockColorStep } from \"core/Materials/Node/Blocks/gradientBlock\";\r\n\r\nconst useGradientStyles = makeStyles({\r\n container: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: tokens.spacingHorizontalXS, // Reduced gap\r\n width: \"100%\",\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n },\r\n // Wrapper for factor spin buttons - fixed width, doesn't grow\r\n valueWrapper: {\r\n flex: \"0 0 auto\", // Fixed size, no grow, no shrink\r\n },\r\n // Wrapper for color pickers - fixed size since they're just swatches\r\n colorWrapper: {\r\n flex: \"0 0 auto\",\r\n alignContent: \"center\",\r\n },\r\n // Wrapper for the step slider - takes remaining space and can shrink\r\n stepSliderWrapper: {\r\n flex: \"1 1 0\", // Grow to fill available space\r\n minWidth: \"100px\", // Minimum to fit slider + spinbutton\r\n },\r\n});\r\n\r\ntype GradientProps<T extends number | Color3 | Color4> = {\r\n value1: T;\r\n value2?: T;\r\n step: number;\r\n};\r\n\r\n/**\r\n * Gradient component that displays 1 or 2 color or number inputs next to a slider\r\n * @param props - Component props containing gradient value and change handlers\r\n * @returns A React component\r\n */\r\nconst Gradient: FunctionComponent<PrimitiveProps<GradientProps<number | Color3 | Color4>>> = (props) => {\r\n Gradient.displayName = \"Gradient\";\r\n const [gradient, setGradient] = useState(props.value);\r\n const classes = useGradientStyles();\r\n\r\n useEffect(() => {\r\n setGradient(props.value); // Re-render if props.value changes\r\n }, [props.value]);\r\n\r\n const gradientChange = (newGradient: GradientProps<number | Color3 | Color4>) => {\r\n setGradient(newGradient);\r\n props.onChange(newGradient);\r\n };\r\n // Only use compact mode when there are numeric values (spinbuttons) taking up space\r\n const hasNumericValues =\r\n !(gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4) ||\r\n (gradient.value2 !== undefined && !(gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4));\r\n\r\n return (\r\n <div id=\"gradientContainer\" className={classes.container}>\r\n <div className={gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4 ? classes.colorWrapper : classes.valueWrapper}>\r\n {gradient.value1 instanceof Color3 || gradient.value1 instanceof Color4 ? (\r\n <ColorPickerPopup value={gradient.value1} onChange={(color) => gradientChange({ ...gradient, value1: color })} />\r\n ) : (\r\n <SyncedSliderInput step={0.01} value={gradient.value1} onChange={(val) => gradientChange({ ...gradient, value1: val })} compact />\r\n )}\r\n </div>\r\n {gradient.value2 !== undefined && (\r\n <div className={gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4 ? classes.colorWrapper : classes.valueWrapper}>\r\n {gradient.value2 instanceof Color3 || gradient.value2 instanceof Color4 ? (\r\n <ColorPickerPopup value={gradient.value2} onChange={(color) => gradientChange({ ...gradient, value2: color })} />\r\n ) : (\r\n <SyncedSliderInput step={0.01} value={gradient.value2} onChange={(val) => gradientChange({ ...gradient, value2: val })} compact />\r\n )}\r\n </div>\r\n )}\r\n\r\n <div className={classes.stepSliderWrapper}>\r\n <SyncedSliderInput\r\n notifyOnlyOnRelease={true}\r\n min={0}\r\n max={1}\r\n step={0.01}\r\n value={gradient.step}\r\n onChange={(val) => gradientChange({ ...gradient, step: val })}\r\n compact={hasNumericValues}\r\n growSlider={!hasNumericValues}\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nconst FactorGradientCast = Gradient as FunctionComponent<PrimitiveProps<GradientProps<number>>>;\r\nconst Color3GradientCast = Gradient as FunctionComponent<PrimitiveProps<GradientProps<Color3>>>;\r\nconst Color4GradientCast = Gradient as FunctionComponent<PrimitiveProps<GradientProps<Color4>>>;\r\n\r\n/**\r\n * Component wrapper for FactorGradient that provides slider inputs for factor1, factor2, and gradient step\r\n * @param props - Component props containing FactorGradient value and change handler\r\n * @returns A React component\r\n */\r\nexport const FactorGradientComponent: FunctionComponent<PrimitiveProps<FactorGradient>> = (props) => {\r\n return (\r\n <FactorGradientCast\r\n {...props}\r\n value={{ value1: props.value.factor1, value2: props.value.factor2, step: props.value.gradient }}\r\n onChange={(gradient) => props.onChange(new FactorGradient(gradient.step, gradient.value1, gradient.value2))}\r\n />\r\n );\r\n};\r\n/**\r\n * Component wrapper for Color3Gradient that provides color picker and gradient step slider\r\n * @param props - Component props containing Color3Gradient value and change handler\r\n * @returns A React component\r\n */\r\nexport const Color3GradientComponent: FunctionComponent<PrimitiveProps<Color3Gradient>> = (props) => {\r\n return (\r\n <Color3GradientCast\r\n {...props}\r\n value={{ value1: props.value.color, step: props.value.gradient }}\r\n onChange={(gradient) => props.onChange(new Color3Gradient(gradient.step, gradient.value1))}\r\n />\r\n );\r\n};\r\n/**\r\n * Component wrapper for Color4Gradient that provides color pickers for color1, color2, and gradient step slider\r\n * @param props - Component props containing Color4Gradient value and change handler\r\n * @returns A React component\r\n */\r\nexport const Color4GradientComponent: FunctionComponent<PrimitiveProps<Color4Gradient>> = (props) => {\r\n return (\r\n <Color4GradientCast\r\n {...props}\r\n value={{ value1: props.value.color1, value2: props.value.color2, step: props.value.gradient }}\r\n onChange={(gradient) => props.onChange(new Color4Gradient(gradient.step, gradient.value1, gradient.value2))}\r\n />\r\n );\r\n};\r\n/**\r\n * Component wrapper for GradientBlockColorStep that provides color picker and step slider\r\n * @param props - Component props containing GradientBlockColorStep value and change handler\r\n * @returns A React component\r\n */\r\nexport const ColorStepGradientComponent: FunctionComponent<PrimitiveProps<GradientBlockColorStep>> = (props) => {\r\n return (\r\n <Color3GradientCast\r\n {...props}\r\n value={{ value1: props.value.color, step: props.value.step }}\r\n onChange={(gradient) => props.onChange(new GradientBlockColorStep(gradient.step, gradient.value1))}\r\n />\r\n );\r\n};\r\n"]}
@@ -12,6 +12,8 @@ export type LinkProps = ImmutablePrimitiveProps<string> & {
12
12
  * Defines whether to open the link in current tab or new tab. Default is new
13
13
  */
14
14
  target?: "current" | "new";
15
+ /**Force link size */
16
+ size?: "small" | "medium";
15
17
  };
16
18
  export declare const Link: import("react").ForwardRefExoticComponent<import("./primitive.js").BasePrimitiveProps & {
17
19
  value: string;
@@ -29,6 +31,8 @@ export declare const Link: import("react").ForwardRefExoticComponent<import("./p
29
31
  * Defines whether to open the link in current tab or new tab. Default is new
30
32
  */
31
33
  target?: "current" | "new";
34
+ /**Force link size */
35
+ size?: "small" | "medium";
32
36
  } & {
33
37
  children?: import("react").ReactNode | undefined;
34
38
  } & import("react").RefAttributes<HTMLAnchorElement>>;
@@ -1,10 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { forwardRef, useContext } from "react";
2
+ import { forwardRef } from "react";
3
3
  import { Body1, Caption1, Link as FluentLink } from "@fluentui/react-components";
4
- import { ToolContext } from "../hoc/fluentToolWrapper.js";
5
4
  export const Link = forwardRef((props, ref) => {
6
- const { size } = useContext(ToolContext);
7
- const { target, url, onLink, ...rest } = props;
5
+ const { target, url, onLink, size, ...rest } = props;
8
6
  // eslint-disable-next-line @typescript-eslint/naming-convention
9
7
  const TextComponent = size === "small" ? Caption1 : Body1;
10
8
  return (_jsxs(FluentLink, { ref: ref, inline: true, target: target === "current" ? "_self" : "_blank", rel: "noopener noreferrer", href: url, onClick: onLink ?? undefined, ...rest, children: [props.children, _jsx(TextComponent, { children: props.value })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/link.tsx"],"names":[],"mappings":";AAIA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAiBvD,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAkD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC3F,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAC/C,gEAAgE;IAChE,MAAM,aAAa,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAE1D,OAAO,CACH,MAAC,UAAU,IAAC,GAAG,EAAE,GAAG,EAAE,MAAM,QAAC,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAC,qBAAqB,EAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,IAAI,SAAS,KAAM,IAAI,aACtJ,KAAK,CAAC,QAAQ,EACf,KAAC,aAAa,cAAE,KAAK,CAAC,KAAK,GAAiB,IACnC,CAChB,CAAC;AACN,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC","sourcesContent":["import type { PropsWithChildren } from \"react\";\r\n\r\nimport type { ImmutablePrimitiveProps } from \"./primitive\";\r\n\r\nimport { forwardRef, useContext } from \"react\";\r\nimport { Body1, Caption1, Link as FluentLink } from \"@fluentui/react-components\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nexport type LinkProps = ImmutablePrimitiveProps<string> & {\r\n /**\r\n * Used if you want to handle the link click yourself\r\n */\r\n onLink?: () => void;\r\n /**\r\n * The URL the link points to\r\n */\r\n url?: string;\r\n /**\r\n * Defines whether to open the link in current tab or new tab. Default is new\r\n */\r\n target?: \"current\" | \"new\";\r\n};\r\n\r\nexport const Link = forwardRef<HTMLAnchorElement, PropsWithChildren<LinkProps>>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const { target, url, onLink, ...rest } = props;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const TextComponent = size === \"small\" ? Caption1 : Body1;\r\n\r\n return (\r\n <FluentLink ref={ref} inline target={target === \"current\" ? \"_self\" : \"_blank\"} rel=\"noopener noreferrer\" href={url} onClick={onLink ?? undefined} {...rest}>\r\n {props.children}\r\n <TextComponent>{props.value}</TextComponent>\r\n </FluentLink>\r\n );\r\n});\r\nLink.displayName = \"Link\";\r\n"]}
1
+ {"version":3,"file":"link.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/link.tsx"],"names":[],"mappings":";AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAoBjF,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAkD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC3F,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IACrD,gEAAgE;IAChE,MAAM,aAAa,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAE1D,OAAO,CACH,MAAC,UAAU,IAAC,GAAG,EAAE,GAAG,EAAE,MAAM,QAAC,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAC,qBAAqB,EAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,IAAI,SAAS,KAAM,IAAI,aACtJ,KAAK,CAAC,QAAQ,EACf,KAAC,aAAa,cAAE,KAAK,CAAC,KAAK,GAAiB,IACnC,CAChB,CAAC;AACN,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC","sourcesContent":["import type { PropsWithChildren } from \"react\";\r\n\r\nimport type { ImmutablePrimitiveProps } from \"./primitive\";\r\n\r\nimport { forwardRef } from \"react\";\r\nimport { Body1, Caption1, Link as FluentLink } from \"@fluentui/react-components\";\r\n\r\nexport type LinkProps = ImmutablePrimitiveProps<string> & {\r\n /**\r\n * Used if you want to handle the link click yourself\r\n */\r\n onLink?: () => void;\r\n /**\r\n * The URL the link points to\r\n */\r\n url?: string;\r\n /**\r\n * Defines whether to open the link in current tab or new tab. Default is new\r\n */\r\n target?: \"current\" | \"new\";\r\n\r\n /**Force link size */\r\n size?: \"small\" | \"medium\";\r\n};\r\n\r\nexport const Link = forwardRef<HTMLAnchorElement, PropsWithChildren<LinkProps>>((props, ref) => {\r\n const { target, url, onLink, size, ...rest } = props;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const TextComponent = size === \"small\" ? Caption1 : Body1;\r\n\r\n return (\r\n <FluentLink ref={ref} inline target={target === \"current\" ? \"_self\" : \"_blank\"} rel=\"noopener noreferrer\" href={url} onClick={onLink ?? undefined} {...rest}>\r\n {props.children}\r\n <TextComponent>{props.value}</TextComponent>\r\n </FluentLink>\r\n );\r\n});\r\nLink.displayName = \"Link\";\r\n"]}
@@ -1,4 +1,4 @@
1
- import type { ReactNode, ReactElement } from "react";
1
+ import type { ReactElement, ReactNode } from "react";
2
2
  /**
3
3
  * Represents an item in a list
4
4
  */
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { CopyRegular, DeleteRegular } from "@fluentui/react-icons";
3
- import { ButtonLine } from "../hoc/buttonLine.js";
4
2
  import { Body1Strong, makeStyles, tokens } from "@fluentui/react-components";
3
+ import { AddRegular, CopyRegular, DeleteRegular } from "@fluentui/react-icons";
4
+ import { useMemo } from "react";
5
+ import { ButtonLine } from "../hoc/buttonLine.js";
5
6
  const useListStyles = makeStyles({
6
7
  item: {
7
8
  width: "100%",
@@ -36,8 +37,7 @@ const useListStyles = makeStyles({
36
37
  export function List(props) {
37
38
  const { items, renderItem, onDelete, onAdd, addButtonLabel = "Add new item" } = props;
38
39
  const classes = useListStyles();
39
- return (_jsxs("div", { children: [_jsx(ButtonLine, { label: addButtonLabel, onClick: () => props.onAdd() }), _jsx("div", { className: classes.list, children: items
40
- .sort((a, b) => a.sortBy - b.sortBy)
41
- .map((item, index) => (_jsxs("div", { className: classes.item, children: [_jsxs(Body1Strong, { className: classes.itemId, children: ["#", index] }), _jsx("div", { className: classes.itemContent, children: renderItem(item, index) }), _jsxs("div", { className: classes.iconContainer, children: [_jsx(CopyRegular, { onClick: () => onAdd(item) }), _jsx(DeleteRegular, { onClick: () => onDelete(item, index) })] })] }, item.id))) })] }));
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))) })] }));
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":";AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAE7E,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,OAAO,CACH,0BACI,KAAC,UAAU,IAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,GAAI,EAEnE,cAAK,SAAS,EAAE,OAAO,CAAC,IAAI,YACvB,KAAK;qBACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;qBACnC,GAAG,CAAC,CAAC,IAAiB,EAAE,KAAa,EAAE,EAAE,CAAC,CACvC,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,GAAO,EACpE,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,GAAI,IACrD,KANA,IAAI,CAAC,EAAE,CAOX,CACT,CAAC,GACJ,IACJ,CACT,CAAC;AACN,CAAC","sourcesContent":["import { CopyRegular, DeleteRegular } from \"@fluentui/react-icons\";\r\nimport type { ReactNode, ReactElement } from \"react\";\r\nimport { ButtonLine } from \"../hoc/buttonLine\";\r\nimport { Body1Strong, makeStyles, tokens } from \"@fluentui/react-components\";\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 return (\r\n <div>\r\n <ButtonLine label={addButtonLabel} onClick={() => props.onAdd()} />\r\n\r\n <div className={classes.list}>\r\n {items\r\n .sort((a, b) => a.sortBy - b.sortBy)\r\n .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, index)}</div>\r\n <div className={classes.iconContainer}>\r\n <CopyRegular onClick={() => onAdd(item)} />\r\n <DeleteRegular onClick={() => onDelete(item, 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,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"]}
@@ -9,5 +9,7 @@ export type SpinButtonProps = PrimitiveProps<number> & {
9
9
  unit?: string;
10
10
  forceInt?: boolean;
11
11
  validator?: (value: number) => boolean;
12
+ /** Optional className for the input element */
13
+ inputClassName?: string;
12
14
  };
13
15
  export declare const SpinButton: FunctionComponent<SpinButtonProps>;
@@ -51,6 +51,11 @@ export const SpinButton = (props) => {
51
51
  };
52
52
  const id = useId("spin-button");
53
53
  const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : "", props.className);
54
- return (_jsxs("div", { className: classes.container, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentSpinButton, { ...props, input: { className: classes.inputSlot }, step: step, id: id, size: size, precision: precision, displayValue: `${value.toFixed(precision)}${props.unit ? " " + props.unit : ""}`, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: mergedClassName })] }));
54
+ // Build input slot from inputClassName
55
+ const inputSlot = {
56
+ className: mergeClasses(classes.inputSlot, props.inputClassName),
57
+ };
58
+ const spinButton = (_jsx(FluentSpinButton, { ...props, appearance: "outline", input: inputSlot, step: step, id: id, size: size, precision: precision, displayValue: `${value.toFixed(precision)}${props.unit ? " " + props.unit : ""}`, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: mergedClassName }));
59
+ return props.infoLabel ? (_jsxs("div", { className: classes.container, children: [_jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), spinButton] })) : (spinButton);
55
60
  };
56
61
  //# sourceMappingURL=spinButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spinButton.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/spinButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import { SpinButton as FluentSpinButton, mergeClasses, useId } from \"@fluentui/react-components\";\r\nimport type { SpinButtonOnChangeData, SpinButtonChangeEvent } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent, KeyboardEvent } from \"react\";\r\nimport { useEffect, useState, useRef, useContext } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { CalculatePrecision, HandleKeyDown, HandleOnBlur, useInputStyles } from \"./utils\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nexport type SpinButtonProps = PrimitiveProps<number> & {\r\n min?: number;\r\n max?: number;\r\n /** Determines how much the spinbutton increments with the arrow keys. Note this also determines the precision value (# of decimals in display value)\r\n * i.e. if step = 1, precision = 0. step = 0.0089, precision = 4. step = 300, precision = 2. step = 23.00, precision = 2. */\r\n step?: number;\r\n unit?: string;\r\n forceInt?: boolean;\r\n validator?: (value: number) => boolean;\r\n};\r\n\r\nexport const SpinButton: FunctionComponent<SpinButtonProps> = (props) => {\r\n SpinButton.displayName = \"SpinButton\";\r\n const classes = useInputStyles();\r\n const { size } = useContext(ToolContext);\r\n\r\n const { min, max } = props;\r\n\r\n const [value, setValue] = useState(props.value);\r\n const lastCommittedValue = useRef(props.value);\r\n // step and forceInt are not mutually exclusive since there could be cases where you want to forceInt but have spinButton jump >1 int per spin\r\n const step = props.step != undefined ? props.step : props.forceInt ? 1 : undefined;\r\n const precision = Math.min(4, step !== undefined ? Math.max(0, CalculatePrecision(step)) : 2); // If no step, set precision to 2. Regardless, cap precision at 4 to avoid wild numbers\r\n\r\n useEffect(() => {\r\n if (props.value !== lastCommittedValue.current) {\r\n lastCommittedValue.current = props.value;\r\n setValue(props.value); // Update local state when props.value changes\r\n }\r\n }, [props.value]);\r\n\r\n const validateValue = (numericValue: number): boolean => {\r\n const outOfBounds = (min !== undefined && numericValue < min) || (max !== undefined && numericValue > max);\r\n const failsValidator = props.validator && !props.validator(numericValue);\r\n const failsIntCheck = props.forceInt ? !Number.isInteger(numericValue) : false;\r\n const invalid = !!outOfBounds || !!failsValidator || isNaN(numericValue) || !!failsIntCheck;\r\n return !invalid;\r\n };\r\n\r\n const tryCommitValue = (currVal: number) => {\r\n // Only commit if valid and different from last committed value\r\n if (validateValue(currVal) && currVal !== lastCommittedValue.current) {\r\n lastCommittedValue.current = currVal;\r\n props.onChange(currVal);\r\n }\r\n };\r\n\r\n const handleChange = (event: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n if (data.value != null && !Number.isNaN(data.value)) {\r\n setValue(data.value);\r\n tryCommitValue(data.value);\r\n }\r\n };\r\n\r\n const handleKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n\r\n if (event.key !== \"Enter\") {\r\n const currVal = parseFloat((event.target as any).value); // Cannot use currentTarget.value as it won't have the most recently typed value\r\n setValue(currVal);\r\n tryCommitValue(currVal);\r\n }\r\n };\r\n\r\n const id = useId(\"spin-button\");\r\n const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : \"\", props.className);\r\n\r\n return (\r\n <div className={classes.container}>\r\n {props.infoLabel && <InfoLabel {...props.infoLabel} htmlFor={id} />}\r\n <FluentSpinButton\r\n {...props}\r\n input={{ className: classes.inputSlot }}\r\n step={step}\r\n id={id}\r\n size={size}\r\n precision={precision}\r\n displayValue={`${value.toFixed(precision)}${props.unit ? \" \" + props.unit : \"\"}`}\r\n value={value}\r\n onChange={handleChange}\r\n onKeyUp={handleKeyUp}\r\n onKeyDown={HandleKeyDown}\r\n onBlur={HandleOnBlur}\r\n className={mergedClassName}\r\n />\r\n </div>\r\n );\r\n};\r\n"]}
1
+ {"version":3,"file":"spinButton.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/spinButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import { SpinButton as FluentSpinButton, mergeClasses, useId } from \"@fluentui/react-components\";\r\nimport type { SpinButtonOnChangeData, SpinButtonChangeEvent } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent, KeyboardEvent } from \"react\";\r\nimport { useEffect, useState, useRef, useContext } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { CalculatePrecision, HandleKeyDown, HandleOnBlur, useInputStyles } from \"./utils\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nexport type SpinButtonProps = PrimitiveProps<number> & {\r\n min?: number;\r\n max?: number;\r\n /** Determines how much the spinbutton increments with the arrow keys. Note this also determines the precision value (# of decimals in display value)\r\n * i.e. if step = 1, precision = 0. step = 0.0089, precision = 4. step = 300, precision = 2. step = 23.00, precision = 2. */\r\n step?: number;\r\n unit?: string;\r\n forceInt?: boolean;\r\n validator?: (value: number) => boolean;\r\n /** Optional className for the input element */\r\n inputClassName?: string;\r\n};\r\n\r\nexport const SpinButton: FunctionComponent<SpinButtonProps> = (props) => {\r\n SpinButton.displayName = \"SpinButton\";\r\n const classes = useInputStyles();\r\n const { size } = useContext(ToolContext);\r\n\r\n const { min, max } = props;\r\n\r\n const [value, setValue] = useState(props.value);\r\n const lastCommittedValue = useRef(props.value);\r\n // step and forceInt are not mutually exclusive since there could be cases where you want to forceInt but have spinButton jump >1 int per spin\r\n const step = props.step != undefined ? props.step : props.forceInt ? 1 : undefined;\r\n const precision = Math.min(4, step !== undefined ? Math.max(0, CalculatePrecision(step)) : 2); // If no step, set precision to 2. Regardless, cap precision at 4 to avoid wild numbers\r\n\r\n useEffect(() => {\r\n if (props.value !== lastCommittedValue.current) {\r\n lastCommittedValue.current = props.value;\r\n setValue(props.value); // Update local state when props.value changes\r\n }\r\n }, [props.value]);\r\n\r\n const validateValue = (numericValue: number): boolean => {\r\n const outOfBounds = (min !== undefined && numericValue < min) || (max !== undefined && numericValue > max);\r\n const failsValidator = props.validator && !props.validator(numericValue);\r\n const failsIntCheck = props.forceInt ? !Number.isInteger(numericValue) : false;\r\n const invalid = !!outOfBounds || !!failsValidator || isNaN(numericValue) || !!failsIntCheck;\r\n return !invalid;\r\n };\r\n\r\n const tryCommitValue = (currVal: number) => {\r\n // Only commit if valid and different from last committed value\r\n if (validateValue(currVal) && currVal !== lastCommittedValue.current) {\r\n lastCommittedValue.current = currVal;\r\n props.onChange(currVal);\r\n }\r\n };\r\n\r\n const handleChange = (event: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n if (data.value != null && !Number.isNaN(data.value)) {\r\n setValue(data.value);\r\n tryCommitValue(data.value);\r\n }\r\n };\r\n\r\n const handleKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n\r\n if (event.key !== \"Enter\") {\r\n const currVal = parseFloat((event.target as any).value); // Cannot use currentTarget.value as it won't have the most recently typed value\r\n setValue(currVal);\r\n tryCommitValue(currVal);\r\n }\r\n };\r\n\r\n const id = useId(\"spin-button\");\r\n const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : \"\", props.className);\r\n\r\n // Build input slot from inputClassName\r\n const inputSlot = {\r\n className: mergeClasses(classes.inputSlot, props.inputClassName),\r\n };\r\n\r\n const spinButton = (\r\n <FluentSpinButton\r\n {...props}\r\n appearance=\"outline\"\r\n input={inputSlot}\r\n step={step}\r\n id={id}\r\n size={size}\r\n precision={precision}\r\n displayValue={`${value.toFixed(precision)}${props.unit ? \" \" + props.unit : \"\"}`}\r\n value={value}\r\n onChange={handleChange}\r\n onKeyUp={handleKeyUp}\r\n onKeyDown={HandleKeyDown}\r\n onBlur={HandleOnBlur}\r\n className={mergedClassName}\r\n />\r\n );\r\n\r\n return props.infoLabel ? (\r\n <div className={classes.container}>\r\n <InfoLabel {...props.infoLabel} htmlFor={id} />\r\n {spinButton}\r\n </div>\r\n ) : (\r\n spinButton\r\n );\r\n};\r\n"]}
@@ -11,8 +11,10 @@ export type SyncedSliderProps = PrimitiveProps<number> & {
11
11
  unit?: string;
12
12
  /** When true, onChange is only called when the user releases the slider, not during drag */
13
13
  notifyOnlyOnRelease?: boolean;
14
- /** When true, slider grows to fill space and SpinButton is fixed at 70px */
14
+ /** When true, slider grows to fill space and SpinButton is fixed at 65px */
15
15
  compact?: boolean;
16
+ /** When true, slider grows to fill all available space (no maxWidth constraint) */
17
+ growSlider?: boolean;
16
18
  };
17
19
  /**
18
20
  * Component which synchronizes a slider and an input field, allowing the user to change the value using either control
@@ -3,24 +3,38 @@ import { makeStyles, Slider } from "@fluentui/react-components";
3
3
  import { SpinButton } from "./spinButton.js";
4
4
  import { useEffect, useState, useRef, useContext } from "react";
5
5
  import { InfoLabel } from "./infoLabel.js";
6
- import { CustomTokens } from "./utils.js";
7
6
  import { ToolContext } from "../hoc/fluentToolWrapper.js";
8
7
  const useSyncedSliderStyles = makeStyles({
9
- container: { display: "flex" },
8
+ container: { display: "flex", minWidth: 0 },
10
9
  syncedSlider: {
11
10
  flex: "1 1 0",
12
11
  flexDirection: "row",
13
12
  display: "flex",
14
13
  alignItems: "center",
14
+ minWidth: 0,
15
15
  },
16
16
  slider: {
17
- flex: "1 1 auto", // Grow to fill available space
18
- minWidth: CustomTokens.sliderMinWidth,
19
- maxWidth: "none", // Allow slider to grow
17
+ flex: "1 1 auto",
18
+ minWidth: "75px",
19
+ maxWidth: "75px",
20
+ },
21
+ compactSlider: {
22
+ flex: "1 1 auto",
23
+ minWidth: "50px", // Allow shrinking for compact mode
24
+ maxWidth: "75px",
25
+ },
26
+ growSlider: {
27
+ flex: "1 1 auto",
28
+ minWidth: "50px",
29
+ // No maxWidth - slider grows to fill available space
20
30
  },
21
31
  compactSpinButton: {
22
- width: "70px",
23
- flex: "0 0 auto", // Don't grow, stay fixed
32
+ width: "65px",
33
+ minWidth: "65px",
34
+ maxWidth: "65px",
35
+ },
36
+ compactSpinButtonInput: {
37
+ minWidth: "0",
24
38
  },
25
39
  });
26
40
  /**
@@ -71,6 +85,17 @@ export const SyncedSliderInput = (props) => {
71
85
  setValue(value);
72
86
  props.onChange(value); // Input always updates immediately
73
87
  };
74
- return (_jsxs("div", { className: classes.container, children: [infoLabel && _jsx(InfoLabel, { ...infoLabel, htmlFor: "syncedSlider" }), _jsxs("div", { id: "syncedSlider", className: classes.syncedSlider, children: [props.min !== undefined && props.max !== undefined && (_jsx(Slider, { ...passthroughProps, className: classes.slider, size: size, min: min / step, max: max / step, step: undefined, value: value / step, onChange: handleSliderChange, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), _jsx(SpinButton, { ...passthroughProps, className: props.compact ? classes.compactSpinButton : undefined, value: value, onChange: handleInputChange, step: props.step })] })] }));
88
+ const hasSlider = props.min !== undefined && props.max !== undefined;
89
+ // Determine Slider className based on props
90
+ const getSliderClassName = () => {
91
+ if (props.growSlider) {
92
+ return classes.growSlider;
93
+ }
94
+ if (props.compact) {
95
+ return classes.compactSlider;
96
+ }
97
+ return classes.slider;
98
+ };
99
+ return (_jsxs("div", { className: classes.container, children: [infoLabel && _jsx(InfoLabel, { ...infoLabel, htmlFor: "syncedSlider" }), _jsxs("div", { id: "syncedSlider", className: classes.syncedSlider, children: [hasSlider && (_jsx(Slider, { ...passthroughProps, className: getSliderClassName(), size: size, min: min / step, max: max / step, step: undefined, value: value / step, onChange: handleSliderChange, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), _jsx(SpinButton, { ...passthroughProps, className: hasSlider || props.compact ? classes.compactSpinButton : undefined, inputClassName: hasSlider || props.compact ? classes.compactSpinButtonInput : undefined, value: value, onChange: handleInputChange, step: props.step })] })] }));
75
100
  };
76
101
  //# sourceMappingURL=syncedSlider.js.map
@@ -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 { CustomTokens } from \"./utils\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nconst useSyncedSliderStyles = makeStyles({\r\n container: { display: \"flex\" },\r\n syncedSlider: {\r\n flex: \"1 1 0\",\r\n flexDirection: \"row\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n },\r\n slider: {\r\n flex: \"1 1 auto\", // Grow to fill available space\r\n minWidth: CustomTokens.sliderMinWidth,\r\n maxWidth: \"none\", // Allow slider to grow\r\n },\r\n compactSpinButton: {\r\n width: \"70px\",\r\n flex: \"0 0 auto\", // Don't grow, stay fixed\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 70px */\r\n compact?: 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 return (\r\n <div className={classes.container}>\r\n {infoLabel && <InfoLabel {...infoLabel} htmlFor={\"syncedSlider\"} />}\r\n <div id=\"syncedSlider\" className={classes.syncedSlider}>\r\n {props.min !== undefined && props.max !== undefined && (\r\n <Slider\r\n {...passthroughProps}\r\n className={classes.slider}\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 {...passthroughProps} className={props.compact ? classes.compactSpinButton : undefined} value={value} onChange={handleInputChange} step={props.step} />\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);\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,5 +1,21 @@
1
1
  import type { GriffelStyle } from "@fluentui/react-components";
2
2
  import type { KeyboardEvent, FocusEvent } from "react";
3
+ export declare const TokenMap: {
4
+ px2: string;
5
+ px4: string;
6
+ px6: string;
7
+ px8: string;
8
+ px10: string;
9
+ px12: string;
10
+ px14: string;
11
+ px16: string;
12
+ px20: string;
13
+ px24: string;
14
+ px28: string;
15
+ px32: string;
16
+ px36: string;
17
+ px40: string;
18
+ };
3
19
  export declare const CustomTokens: {
4
20
  inputWidth: string;
5
21
  lineHeight: string;
@@ -1,14 +1,30 @@
1
1
  import { makeStyles, tokens } from "@fluentui/react-components";
2
+ export const TokenMap = {
3
+ px2: tokens.borderRadiusSmall,
4
+ px4: tokens.borderRadiusMedium,
5
+ px6: tokens.borderRadiusLarge,
6
+ px8: tokens.borderRadiusXLarge,
7
+ px10: tokens.fontSizeBase100,
8
+ px12: tokens.fontSizeBase200,
9
+ px14: tokens.fontSizeBase300,
10
+ px16: tokens.fontSizeBase400,
11
+ px20: tokens.fontSizeBase500,
12
+ px24: tokens.fontSizeBase600,
13
+ px28: tokens.lineHeightBase500,
14
+ px32: tokens.lineHeightBase600,
15
+ px36: tokens.lineHeightHero700,
16
+ px40: tokens.lineHeightHero800,
17
+ };
2
18
  export const CustomTokens = {
3
19
  inputWidth: "150px",
4
- lineHeight: tokens.lineHeightHero700, // 36px
5
- lineHeightSmall: tokens.lineHeightBase500, // 28px
6
- dividerGap: tokens.fontSizeBase100, // "10px",
7
- dividerGapSmall: tokens.borderRadiusMedium, // 4px",
20
+ lineHeight: TokenMap.px36,
21
+ lineHeightSmall: TokenMap.px28,
22
+ dividerGap: TokenMap.px10,
23
+ dividerGapSmall: TokenMap.px4,
8
24
  labelMinWidth: "50px",
9
25
  sliderMinWidth: "30px",
10
26
  sliderMaxWidth: "80px",
11
- rightAlignOffset: `-${tokens.borderRadiusXLarge}`, // -8px
27
+ rightAlignOffset: `-${TokenMap.px8}`,
12
28
  };
13
29
  export const UniformWidthStyling = { width: CustomTokens.inputWidth, boxSizing: "border-box" };
14
30
  export const useInputStyles = makeStyles({
@@ -16,10 +32,10 @@ export const useInputStyles = makeStyles({
16
32
  inputSlot: { textAlign: "right" },
17
33
  invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },
18
34
  container: {
19
- flex: 1,
20
35
  display: "flex",
21
36
  flexDirection: "column",
22
37
  justifyContent: "center", // align items vertically
38
+ minWidth: 0, // Allow shrinking
23
39
  },
24
40
  });
25
41
  export function HandleOnBlur(event) {
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAKhE,MAAM,CAAC,MAAM,YAAY,GAAG;IACxB,UAAU,EAAE,OAAO;IACnB,UAAU,EAAE,MAAM,CAAC,iBAAiB,EAAE,OAAO;IAC7C,eAAe,EAAE,MAAM,CAAC,iBAAiB,EAAE,OAAO;IAClD,UAAU,EAAE,MAAM,CAAC,eAAe,EAAE,UAAU;IAC9C,eAAe,EAAE,MAAM,CAAC,kBAAkB,EAAE,QAAQ;IACpD,aAAa,EAAE,MAAM;IACrB,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,MAAM;IACtB,gBAAgB,EAAE,IAAI,MAAM,CAAC,kBAAkB,EAAE,EAAE,OAAO;CAC7D,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAiB,EAAE,KAAK,EAAE,YAAY,CAAC,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;AAC7G,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;IACrC,KAAK,EAAE,mBAAmB;IAC1B,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE;IACjC,OAAO,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,0BAA0B,EAAE;IAC/D,SAAS,EAAE;QACP,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,cAAc,EAAE,QAAQ,EAAE,yBAAyB;KACtD;CACJ,CAAC,CAAC;AAEH,MAAM,UAAU,YAAY,CAAC,KAAmC;IAC5D,KAAK,CAAC,eAAe,EAAE,CAAC;IACxB,KAAK,CAAC,cAAc,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAsC;IAChE,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,4BAA4B;IAErD,oEAAoE;IACpE,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;QACxB,KAAK,CAAC,cAAc,EAAE,CAAC;IAC3B,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC5C;;;;;OAKG,CAAC,MAAM,MAAM,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,CAAC;IACb,CAAC;IACD,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7B,CAAC;IACD,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5B,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAED,MAAM,SAAS,GAAG,MAAM,CAAC,mDAAmD,CAAC,CAAC;AAC9E,MAAM,UAAU,gBAAgB,CAAC,GAAW;IACxC,OAAO,GAAG,IAAI,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5C,CAAC","sourcesContent":["import { makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport type { GriffelStyle } from \"@fluentui/react-components\";\r\n\r\nimport type { KeyboardEvent, FocusEvent } from \"react\";\r\n\r\nexport const CustomTokens = {\r\n inputWidth: \"150px\",\r\n lineHeight: tokens.lineHeightHero700, // 36px\r\n lineHeightSmall: tokens.lineHeightBase500, // 28px\r\n dividerGap: tokens.fontSizeBase100, // \"10px\",\r\n dividerGapSmall: tokens.borderRadiusMedium, // 4px\",\r\n labelMinWidth: \"50px\",\r\n sliderMinWidth: \"30px\",\r\n sliderMaxWidth: \"80px\",\r\n rightAlignOffset: `-${tokens.borderRadiusXLarge}`, // -8px\r\n};\r\n\r\nexport const UniformWidthStyling: GriffelStyle = { width: CustomTokens.inputWidth, boxSizing: \"border-box\" };\r\nexport const useInputStyles = makeStyles({\r\n input: UniformWidthStyling,\r\n inputSlot: { textAlign: \"right\" },\r\n invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },\r\n container: {\r\n flex: 1,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"center\", // align items vertically\r\n },\r\n});\r\n\r\nexport function HandleOnBlur(event: FocusEvent<HTMLInputElement>) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n}\r\n\r\nexport function HandleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\r\n event.stopPropagation(); // Prevent event propagation\r\n\r\n // Prevent Enter key from causing form submission or value reversion\r\n if (event.key === \"Enter\") {\r\n event.preventDefault();\r\n }\r\n}\r\n\r\n/**\r\n * Fluent's CalculatePrecision function\r\n * https://github.com/microsoft/fluentui/blob/dcbf775d37938eacffa37922fc0b43a3cdd5753f/packages/utilities/src/math.ts#L91C1\r\n *\r\n * Calculates a number's precision based on the number of trailing\r\n * zeros if the number does not have a decimal indicated by a negative\r\n * precision. Otherwise, it calculates the number of digits after\r\n * the decimal point indicated by a positive precision.\r\n *\r\n * @param value - the value to determine the precision of\r\n * @returns the calculated precision\r\n */\r\nexport function CalculatePrecision(value: number) {\r\n /**\r\n * Group 1:\r\n * [1-9]([0]+$) matches trailing zeros\r\n * Group 2:\r\n * \\.([0-9]*) matches all digits after a decimal point.\r\n */ const groups = /[1-9]([0]+$)|\\.([0-9]*)/.exec(String(value));\r\n if (!groups) {\r\n return 0;\r\n }\r\n if (groups[1]) {\r\n return -groups[1].length;\r\n }\r\n if (groups[2]) {\r\n return groups[2].length;\r\n }\r\n return 0;\r\n}\r\n\r\nconst HEX_REGEX = RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8})$/);\r\nexport function ValidateColorHex(val: string) {\r\n return val != \"\" && HEX_REGEX.test(val);\r\n}\r\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport type { GriffelStyle } from \"@fluentui/react-components\";\r\n\r\nimport type { KeyboardEvent, FocusEvent } from \"react\";\r\n\r\nexport const TokenMap = {\r\n px2: tokens.borderRadiusSmall,\r\n px4: tokens.borderRadiusMedium,\r\n px6: tokens.borderRadiusLarge,\r\n px8: tokens.borderRadiusXLarge,\r\n px10: tokens.fontSizeBase100,\r\n px12: tokens.fontSizeBase200,\r\n px14: tokens.fontSizeBase300,\r\n px16: tokens.fontSizeBase400,\r\n px20: tokens.fontSizeBase500,\r\n px24: tokens.fontSizeBase600,\r\n px28: tokens.lineHeightBase500,\r\n px32: tokens.lineHeightBase600,\r\n px36: tokens.lineHeightHero700,\r\n px40: tokens.lineHeightHero800,\r\n};\r\n\r\nexport const CustomTokens = {\r\n inputWidth: \"150px\",\r\n lineHeight: TokenMap.px36,\r\n lineHeightSmall: TokenMap.px28,\r\n dividerGap: TokenMap.px10,\r\n dividerGapSmall: TokenMap.px4,\r\n labelMinWidth: \"50px\",\r\n sliderMinWidth: \"30px\",\r\n sliderMaxWidth: \"80px\",\r\n rightAlignOffset: `-${TokenMap.px8}`,\r\n};\r\n\r\nexport const UniformWidthStyling: GriffelStyle = { width: CustomTokens.inputWidth, boxSizing: \"border-box\" };\r\nexport const useInputStyles = makeStyles({\r\n input: UniformWidthStyling,\r\n inputSlot: { textAlign: \"right\" },\r\n invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },\r\n container: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"center\", // align items vertically\r\n minWidth: 0, // Allow shrinking\r\n },\r\n});\r\n\r\nexport function HandleOnBlur(event: FocusEvent<HTMLInputElement>) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n}\r\n\r\nexport function HandleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\r\n event.stopPropagation(); // Prevent event propagation\r\n\r\n // Prevent Enter key from causing form submission or value reversion\r\n if (event.key === \"Enter\") {\r\n event.preventDefault();\r\n }\r\n}\r\n\r\n/**\r\n * Fluent's CalculatePrecision function\r\n * https://github.com/microsoft/fluentui/blob/dcbf775d37938eacffa37922fc0b43a3cdd5753f/packages/utilities/src/math.ts#L91C1\r\n *\r\n * Calculates a number's precision based on the number of trailing\r\n * zeros if the number does not have a decimal indicated by a negative\r\n * precision. Otherwise, it calculates the number of digits after\r\n * the decimal point indicated by a positive precision.\r\n *\r\n * @param value - the value to determine the precision of\r\n * @returns the calculated precision\r\n */\r\nexport function CalculatePrecision(value: number) {\r\n /**\r\n * Group 1:\r\n * [1-9]([0]+$) matches trailing zeros\r\n * Group 2:\r\n * \\.([0-9]*) matches all digits after a decimal point.\r\n */ const groups = /[1-9]([0]+$)|\\.([0-9]*)/.exec(String(value));\r\n if (!groups) {\r\n return 0;\r\n }\r\n if (groups[1]) {\r\n return -groups[1].length;\r\n }\r\n if (groups[2]) {\r\n return groups[2].length;\r\n }\r\n return 0;\r\n}\r\n\r\nconst HEX_REGEX = RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8})$/);\r\nexport function ValidateColorHex(val: string) {\r\n return val != \"\" && HEX_REGEX.test(val);\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onerjs/shared-ui-components",
3
- "version": "8.35.8",
3
+ "version": "8.36.1",
4
4
  "main": "index.js",
5
5
  "module": "index.js",
6
6
  "types": "index.d.ts",