@webiny/admin-ui 0.0.0-unstable.a4f3e4ea8b → 0.0.0-unstable.a85ef555b2

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.
Files changed (152) hide show
  1. package/AutoComplete/primitives/AutoCompletePrimitive.d.ts +6 -0
  2. package/AutoComplete/primitives/AutoCompletePrimitive.js +1 -0
  3. package/AutoComplete/primitives/AutoCompletePrimitive.js.map +1 -1
  4. package/Breadcrumbs/Breadcrumbs.d.ts +54 -0
  5. package/Breadcrumbs/Breadcrumbs.js +66 -0
  6. package/Breadcrumbs/Breadcrumbs.js.map +1 -0
  7. package/Breadcrumbs/Breadcrumbs.stories.d.ts +9 -0
  8. package/Breadcrumbs/Breadcrumbs.stories.js +71 -0
  9. package/Breadcrumbs/Breadcrumbs.stories.js.map +1 -0
  10. package/Breadcrumbs/index.d.ts +1 -0
  11. package/Breadcrumbs/index.js +1 -0
  12. package/Button/Button.d.ts +1 -1
  13. package/Button/Button.js +14 -0
  14. package/Button/Button.js.map +1 -1
  15. package/Button/Button.mdx +13 -0
  16. package/Button/Button.stories.d.ts +1 -0
  17. package/Button/Button.stories.js +10 -2
  18. package/Button/Button.stories.js.map +1 -1
  19. package/Button/Button.test.d.ts +1 -0
  20. package/Button/Button.test.js +28 -0
  21. package/Button/Button.test.js.map +1 -0
  22. package/Checkbox/primitives/presenters/CheckboxPresenter.js +5 -2
  23. package/Checkbox/primitives/presenters/CheckboxPresenter.js.map +1 -1
  24. package/Checkbox/primitives/presenters/CheckboxPresenter.jsxLabel.test.d.ts +1 -0
  25. package/Checkbox/primitives/presenters/CheckboxPresenter.jsxLabel.test.js +61 -0
  26. package/Checkbox/primitives/presenters/CheckboxPresenter.jsxLabel.test.js.map +1 -0
  27. package/CheckboxGroup/primitives/presenters/CheckboxGroupPresenter.js +5 -2
  28. package/CheckboxGroup/primitives/presenters/CheckboxGroupPresenter.js.map +1 -1
  29. package/CheckboxGroup/primitives/presenters/CheckboxGroupPresenter.jsxLabel.test.d.ts +1 -0
  30. package/CheckboxGroup/primitives/presenters/CheckboxGroupPresenter.jsxLabel.test.js +108 -0
  31. package/CheckboxGroup/primitives/presenters/CheckboxGroupPresenter.jsxLabel.test.js.map +1 -0
  32. package/Command/components/List.d.ts +1 -1
  33. package/Command/components/List.js +9 -5
  34. package/Command/components/List.js.map +1 -1
  35. package/DataTable/DataTable.d.ts +16 -6
  36. package/DataTable/DataTable.js +12 -4
  37. package/DataTable/DataTable.js.map +1 -1
  38. package/DataTable/components/ColumnsVisibility.d.ts +5 -4
  39. package/DataTable/components/ColumnsVisibility.js +6 -3
  40. package/DataTable/components/ColumnsVisibility.js.map +1 -1
  41. package/DatePicker/DatePicker.stories.d.ts +10 -0
  42. package/DatePicker/DatePicker.stories.js +44 -1
  43. package/DatePicker/DatePicker.stories.js.map +1 -1
  44. package/DatePicker/primitives/BirthdayPicker.d.ts +13 -0
  45. package/DatePicker/primitives/BirthdayPicker.js +355 -0
  46. package/DatePicker/primitives/BirthdayPicker.js.map +1 -0
  47. package/DatePicker/primitives/BirthdayPickerCell.d.ts +14 -0
  48. package/DatePicker/primitives/BirthdayPickerCell.js +19 -0
  49. package/DatePicker/primitives/BirthdayPickerCell.js.map +1 -0
  50. package/DatePicker/primitives/BirthdayPickerSegments.d.ts +9 -0
  51. package/DatePicker/primitives/BirthdayPickerSegments.js +43 -0
  52. package/DatePicker/primitives/BirthdayPickerSegments.js.map +1 -0
  53. package/DatePicker/primitives/DateOnlyPicker.d.ts +1 -1
  54. package/DatePicker/primitives/DateOnlyPicker.js +12 -4
  55. package/DatePicker/primitives/DateOnlyPicker.js.map +1 -1
  56. package/DatePicker/primitives/DatePickerPrimitive.js +3 -0
  57. package/DatePicker/primitives/DatePickerPrimitive.js.map +1 -1
  58. package/DatePicker/primitives/DateRangePicker.js +3 -3
  59. package/DatePicker/primitives/DateRangePicker.js.map +1 -1
  60. package/DatePicker/primitives/DateTimePicker.js +8 -7
  61. package/DatePicker/primitives/DateTimePicker.js.map +1 -1
  62. package/DatePicker/primitives/MultipleDatesPicker.js +3 -3
  63. package/DatePicker/primitives/MultipleDatesPicker.js.map +1 -1
  64. package/DatePicker/utils/birthdayHelpers.d.ts +77 -0
  65. package/DatePicker/utils/birthdayHelpers.js +145 -0
  66. package/DatePicker/utils/birthdayHelpers.js.map +1 -0
  67. package/DatePicker/utils/birthdayHelpers.test.d.ts +1 -0
  68. package/DatePicker/utils/birthdayHelpers.test.js +394 -0
  69. package/DatePicker/utils/birthdayHelpers.test.js.map +1 -0
  70. package/DatePicker/utils/dateHelpers.d.ts +5 -0
  71. package/DatePicker/utils/dateHelpers.js +11 -4
  72. package/DatePicker/utils/dateHelpers.js.map +1 -1
  73. package/DatePicker/utils/dateHelpers.test.d.ts +1 -0
  74. package/DatePicker/utils/dateHelpers.test.js +119 -0
  75. package/DatePicker/utils/dateHelpers.test.js.map +1 -0
  76. package/DatePicker/utils/index.d.ts +1 -0
  77. package/DatePicker/utils/index.js +1 -0
  78. package/DatePicker/utils/types.d.ts +13 -2
  79. package/Drawer/Drawer.d.ts +10 -6
  80. package/Drawer/Drawer.js +2 -1
  81. package/Drawer/Drawer.js.map +1 -1
  82. package/Drawer/Drawer.stories.d.ts +1 -0
  83. package/Drawer/Drawer.stories.js +20 -2
  84. package/Drawer/Drawer.stories.js.map +1 -1
  85. package/Drawer/components/DrawerHeader.d.ts +2 -2
  86. package/Drawer/components/DrawerHeader.js +11 -8
  87. package/Drawer/components/DrawerHeader.js.map +1 -1
  88. package/Drawer/components/Icon.d.ts +1 -1
  89. package/Drawer/components/Icon.js +3 -4
  90. package/Drawer/components/Icon.js.map +1 -1
  91. package/FilePicker/FilePicker.stories.d.ts +6 -0
  92. package/FilePicker/FilePicker.stories.js +24 -1
  93. package/FilePicker/FilePicker.stories.js.map +1 -1
  94. package/FilePicker/primitives/components/previews/ItemDescription.js +1 -1
  95. package/FilePicker/primitives/components/previews/ItemDescription.js.map +1 -1
  96. package/IconPicker/primitives/IconPickerPrimitive.js +1 -2
  97. package/IconPicker/primitives/IconPickerPrimitive.js.map +1 -1
  98. package/ImageEditor/types.js +1 -1
  99. package/ImageEditor/types.js.map +1 -1
  100. package/Markdown/Markdown.d.ts +47 -0
  101. package/Markdown/Markdown.js +17 -0
  102. package/Markdown/Markdown.js.map +1 -0
  103. package/Markdown/index.d.ts +1 -0
  104. package/Markdown/index.js +1 -0
  105. package/MultiAutoComplete/primitives/MultiAutoCompletePrimitive.d.ts +6 -0
  106. package/MultiAutoComplete/primitives/MultiAutoCompletePrimitive.js +1 -0
  107. package/MultiAutoComplete/primitives/MultiAutoCompletePrimitive.js.map +1 -1
  108. package/MultiSelect/primitives/MultiSelectPrimitive.js +12 -5
  109. package/MultiSelect/primitives/MultiSelectPrimitive.js.map +1 -1
  110. package/Popover/Popover.stories.d.ts +7 -0
  111. package/Popover/Popover.stories.js +24 -1
  112. package/Popover/Popover.stories.js.map +1 -1
  113. package/Popover/primitives/components/PopoverContent.js +6 -1
  114. package/Popover/primitives/components/PopoverContent.js.map +1 -1
  115. package/RadioGroup/primitives/RadioGroupPrimitive.d.ts +1 -1
  116. package/RadioGroup/primitives/RadioGroupPrimitive.js +4 -2
  117. package/RadioGroup/primitives/RadioGroupPrimitive.js.map +1 -1
  118. package/RadioGroup/primitives/presenters/RadioGroupPresenter.js +4 -2
  119. package/RadioGroup/primitives/presenters/RadioGroupPresenter.js.map +1 -1
  120. package/RadioGroup/primitives/presenters/RadioGroupPresenter.jsxLabel.test.d.ts +1 -0
  121. package/RadioGroup/primitives/presenters/RadioGroupPresenter.jsxLabel.test.js +88 -0
  122. package/RadioGroup/primitives/presenters/RadioGroupPresenter.jsxLabel.test.js.map +1 -0
  123. package/ScrollArea/ScrollArea.d.ts +16 -2
  124. package/ScrollArea/ScrollArea.js +19 -5
  125. package/ScrollArea/ScrollArea.js.map +1 -1
  126. package/Select/primitives/components/SelectContent.js +4 -6
  127. package/Select/primitives/components/SelectContent.js.map +1 -1
  128. package/Switch/Switch.d.ts +4 -4
  129. package/Switch/Switch.js +21 -7
  130. package/Switch/Switch.js.map +1 -1
  131. package/Switch/domains/SwitchItemDto.d.ts +1 -1
  132. package/Switch/primitives/SwitchPrimitive.js +4 -3
  133. package/Switch/primitives/SwitchPrimitive.js.map +1 -1
  134. package/Tabs/Tabs.d.ts +7 -2
  135. package/Tabs/Tabs.js +29 -11
  136. package/Tabs/Tabs.js.map +1 -1
  137. package/Tabs/Tabs.mdx +27 -0
  138. package/Tabs/Tabs.stories.d.ts +1 -0
  139. package/Tabs/Tabs.stories.js +19 -1
  140. package/Tabs/Tabs.stories.js.map +1 -1
  141. package/Toast/useToast.stories.js.map +1 -1
  142. package/ToggleGroup/primitives/ToggleGroupPrimitive.js +1 -1
  143. package/ToggleGroup/primitives/ToggleGroupPrimitive.js.map +1 -1
  144. package/hooks/index.d.ts +1 -0
  145. package/hooks/index.js +1 -0
  146. package/hooks/useEscapeScrollLock.d.ts +13 -0
  147. package/hooks/useEscapeScrollLock.js +21 -0
  148. package/hooks/useEscapeScrollLock.js.map +1 -0
  149. package/index.d.ts +2 -0
  150. package/index.js +2 -0
  151. package/package.json +22 -22
  152. package/theme.css +38 -0
@@ -7,10 +7,12 @@ const RadioGroupRoot = ({ className, ...props })=>/*#__PURE__*/ __rspack_externa
7
7
  className: cn("grid gap-sm-extra py-xs-plus", className),
8
8
  ...props
9
9
  });
10
- const RadioGroupRenderer = ({ items, changeValue, value, disabled })=>/*#__PURE__*/ __rspack_external_react.createElement(RadioGroupRoot, {
10
+ const RadioGroupRenderer = ({ items, changeValue, value, disabled, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy })=>/*#__PURE__*/ __rspack_external_react.createElement(RadioGroupRoot, {
11
11
  value: value ?? "",
12
12
  onValueChange: (value)=>changeValue(value),
13
- disabled: disabled
13
+ disabled: disabled,
14
+ "aria-label": ariaLabel,
15
+ "aria-labelledby": ariaLabelledBy
14
16
  }, items.map((item)=>/*#__PURE__*/ __rspack_external_react.createElement(Radio, {
15
17
  id: item.id,
16
18
  value: item.value,
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup/primitives/RadioGroupPrimitive.js","sources":["../../../src/RadioGroup/primitives/RadioGroupPrimitive.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { RadioGroup as RadioGroupPrimitives } from \"radix-ui\";\nimport { cn } from \"~/utils.js\";\nimport { Radio } from \"./Radio.js\";\nimport type { RadioItemParams, RadioItemFormatted } from \"../domains/index.js\";\nimport { useRadioGroup } from \"./useRadioGroup.js\";\n\n/**\n * Radio Group Root\n */\nconst RadioGroupRoot = ({ className, ...props }: RadioGroupPrimitives.RadioGroupProps) => {\n return (\n <RadioGroupPrimitives.Root\n className={cn(\"grid gap-sm-extra py-xs-plus\", className)}\n {...props}\n />\n );\n};\n\n/**\n * Radio Group Renderer\n */\ninterface RadioGroupPrimitiveProps extends Omit<\n RadioGroupPrimitives.RadioGroupProps,\n \"defaultValue\" | \"onChange\" | \"onValueChange\" | \"value\"\n> {\n items: RadioItemParams[];\n /**\n * Callback triggered when the selected value changes.\n */\n onChange?: (value: string) => void;\n /**\n * Optional selected item.\n */\n value?: string;\n}\n\ninterface RadioGroupVm {\n items: RadioItemFormatted[];\n}\n\ninterface RadioGroupRendererProps extends Omit<RadioGroupPrimitiveProps, \"onChange\"> {\n items: RadioItemFormatted[];\n changeValue: (value: string) => void;\n}\n\nconst RadioGroupRenderer = ({ items, changeValue, value, disabled }: RadioGroupRendererProps) => {\n return (\n <RadioGroupRoot\n value={value ?? \"\"}\n onValueChange={value => changeValue(value)}\n disabled={disabled}\n >\n {items.map(item => (\n <Radio\n id={item.id}\n value={item.value}\n key={item.id}\n label={item.label}\n disabled={item.disabled}\n />\n ))}\n </RadioGroupRoot>\n );\n};\n\n/**\n * Radio Group Primitive\n */\nconst RadioGroupPrimitive = (props: RadioGroupPrimitiveProps) => {\n const { vm, changeValue } = useRadioGroup(props);\n return <RadioGroupRenderer {...props} items={vm.items} changeValue={changeValue} />;\n};\n\n/**\n * @deprecated\n * This component is retained in @webiny/admin-ui and used in @webiny/ui solely as a compatibility layer.\n * It is marked as deprecated because nesting `Radio` components inside `RadioGroup` is no longer the recommended approach.\n * Instead, we now pass an array of `RadioItemDto` directly to `RadioGroup` for better maintainability.\n */\nconst DeprecatedRadioGroup = RadioGroupRoot;\n\nexport {\n RadioGroupPrimitive,\n RadioGroupRenderer,\n DeprecatedRadioGroup,\n type RadioGroupPrimitiveProps,\n type RadioGroupVm\n};\n"],"names":["RadioGroupRoot","className","props","RadioGroupPrimitives","cn","RadioGroupRenderer","items","changeValue","value","disabled","item","Radio","RadioGroupPrimitive","vm","useRadioGroup","DeprecatedRadioGroup"],"mappings":";;;;;AAUA,MAAMA,iBAAiB,CAAC,EAAEC,SAAS,EAAE,GAAGC,OAA6C,GAC1E,WAAP,GACI,sCAACC,WAAAA,IAAyB;QACtB,WAAWC,GAAG,gCAAgCH;QAC7C,GAAGC,KAAK;;AAgCrB,MAAMG,qBAAqB,CAAC,EAAEC,KAAK,EAAEC,WAAW,EAAEC,KAAK,EAAEC,QAAQ,EAA2B,GACjF,WAAP,GACI,sCAACT,gBAAcA;QACX,OAAOQ,SAAS;QAChB,eAAeA,CAAAA,QAASD,YAAYC;QACpC,UAAUC;OAETH,MAAM,GAAG,CAACI,CAAAA,OAAAA,WAAAA,GACP,sCAACC,OAAKA;YACF,IAAID,KAAK,EAAE;YACX,OAAOA,KAAK,KAAK;YACjB,KAAKA,KAAK,EAAE;YACZ,OAAOA,KAAK,KAAK;YACjB,UAAUA,KAAK,QAAQ;;AAU3C,MAAME,sBAAsB,CAACV;IACzB,MAAM,EAAEW,EAAE,EAAEN,WAAW,EAAE,GAAGO,cAAcZ;IAC1C,OAAO,WAAP,GAAO,sCAACG,oBAAkBA;QAAE,GAAGH,KAAK;QAAE,OAAOW,GAAG,KAAK;QAAE,aAAaN;;AACxE;AAQA,MAAMQ,uBAAuBf"}
1
+ {"version":3,"file":"RadioGroup/primitives/RadioGroupPrimitive.js","sources":["../../../src/RadioGroup/primitives/RadioGroupPrimitive.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { RadioGroup as RadioGroupPrimitives } from \"radix-ui\";\nimport { cn } from \"~/utils.js\";\nimport { Radio } from \"./Radio.js\";\nimport type { RadioItemParams, RadioItemFormatted } from \"../domains/index.js\";\nimport { useRadioGroup } from \"./useRadioGroup.js\";\n\n/**\n * Radio Group Root\n */\nconst RadioGroupRoot = ({ className, ...props }: RadioGroupPrimitives.RadioGroupProps) => {\n return (\n <RadioGroupPrimitives.Root\n className={cn(\"grid gap-sm-extra py-xs-plus\", className)}\n {...props}\n />\n );\n};\n\n/**\n * Radio Group Renderer\n */\ninterface RadioGroupPrimitiveProps extends Omit<\n RadioGroupPrimitives.RadioGroupProps,\n \"defaultValue\" | \"onChange\" | \"onValueChange\" | \"value\"\n> {\n items: RadioItemParams[];\n /**\n * Callback triggered when the selected value changes.\n */\n onChange?: (value: string) => void;\n /**\n * Optional selected item.\n */\n value?: string;\n}\n\ninterface RadioGroupVm {\n items: RadioItemFormatted[];\n}\n\ninterface RadioGroupRendererProps extends Omit<RadioGroupPrimitiveProps, \"onChange\"> {\n items: RadioItemFormatted[];\n changeValue: (value: string) => void;\n}\n\nconst RadioGroupRenderer = ({\n items,\n changeValue,\n value,\n disabled,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy\n}: RadioGroupRendererProps) => {\n return (\n <RadioGroupRoot\n value={value ?? \"\"}\n onValueChange={value => changeValue(value)}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {items.map(item => (\n <Radio\n id={item.id}\n value={item.value}\n key={item.id}\n label={item.label}\n disabled={item.disabled}\n />\n ))}\n </RadioGroupRoot>\n );\n};\n\n/**\n * Radio Group Primitive\n */\nconst RadioGroupPrimitive = (props: RadioGroupPrimitiveProps) => {\n const { vm, changeValue } = useRadioGroup(props);\n return <RadioGroupRenderer {...props} items={vm.items} changeValue={changeValue} />;\n};\n\n/**\n * @deprecated\n * This component is retained in @webiny/admin-ui and used in @webiny/ui solely as a compatibility layer.\n * It is marked as deprecated because nesting `Radio` components inside `RadioGroup` is no longer the recommended approach.\n * Instead, we now pass an array of `RadioItemDto` directly to `RadioGroup` for better maintainability.\n */\nconst DeprecatedRadioGroup = RadioGroupRoot;\n\nexport {\n RadioGroupPrimitive,\n RadioGroupRenderer,\n DeprecatedRadioGroup,\n type RadioGroupPrimitiveProps,\n type RadioGroupVm\n};\n"],"names":["RadioGroupRoot","className","props","RadioGroupPrimitives","cn","RadioGroupRenderer","items","changeValue","value","disabled","ariaLabel","ariaLabelledBy","item","Radio","RadioGroupPrimitive","vm","useRadioGroup","DeprecatedRadioGroup"],"mappings":";;;;;AAUA,MAAMA,iBAAiB,CAAC,EAAEC,SAAS,EAAE,GAAGC,OAA6C,GAC1E,WAAP,GACI,sCAACC,WAAAA,IAAyB;QACtB,WAAWC,GAAG,gCAAgCH;QAC7C,GAAGC,KAAK;;AAgCrB,MAAMG,qBAAqB,CAAC,EACxBC,KAAK,EACLC,WAAW,EACXC,KAAK,EACLC,QAAQ,EACR,cAAcC,SAAS,EACvB,mBAAmBC,cAAc,EACX,GACf,WAAP,GACI,sCAACX,gBAAcA;QACX,OAAOQ,SAAS;QAChB,eAAeA,CAAAA,QAASD,YAAYC;QACpC,UAAUC;QACV,cAAYC;QACZ,mBAAiBC;OAEhBL,MAAM,GAAG,CAACM,CAAAA,OAAAA,WAAAA,GACP,sCAACC,OAAKA;YACF,IAAID,KAAK,EAAE;YACX,OAAOA,KAAK,KAAK;YACjB,KAAKA,KAAK,EAAE;YACZ,OAAOA,KAAK,KAAK;YACjB,UAAUA,KAAK,QAAQ;;AAU3C,MAAME,sBAAsB,CAACZ;IACzB,MAAM,EAAEa,EAAE,EAAER,WAAW,EAAE,GAAGS,cAAcd;IAC1C,OAAO,WAAP,GAAO,sCAACG,oBAAkBA;QAAE,GAAGH,KAAK;QAAE,OAAOa,GAAG,KAAK;QAAE,aAAaR;;AACxE;AAQA,MAAMU,uBAAuBjB"}
@@ -1,4 +1,4 @@
1
- import { makeAutoObservable } from "mobx";
1
+ import { makeAutoObservable, observableRef } from "mobx";
2
2
  import { RadioItem } from "../../domains/RadioItem.js";
3
3
  import { RadioItemFormatter } from "../../domains/RadioItemFormatter.js";
4
4
  class RadioGroupPresenter {
@@ -10,7 +10,9 @@ class RadioGroupPresenter {
10
10
  this.changeValue = (value)=>{
11
11
  this.params?.onValueChange?.(value);
12
12
  };
13
- makeAutoObservable(this);
13
+ makeAutoObservable(this, {
14
+ params: observableRef
15
+ });
14
16
  }
15
17
  get vm() {
16
18
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup/primitives/presenters/RadioGroupPresenter.js","sources":["../../../../src/RadioGroup/primitives/presenters/RadioGroupPresenter.ts"],"sourcesContent":["import { makeAutoObservable } from \"mobx\";\nimport type { RadioGroupVm } from \"../RadioGroupPrimitive.js\";\nimport { RadioItem } from \"~/RadioGroup/domains/RadioItem.js\";\nimport { RadioItemFormatter } from \"~/RadioGroup/domains/RadioItemFormatter.js\";\nimport type { RadioItemParams } from \"~/RadioGroup/domains/RadioItemParams.js\";\n\ninterface RadioGroupPresenterParams<TValue = string> {\n items: RadioItemParams[];\n onValueChange?: (value: TValue) => void;\n}\n\ninterface IRadioGroupPresenter<TValue = string> {\n vm: RadioGroupVm;\n init: (props: RadioGroupPresenterParams<TValue>) => void;\n changeValue: (value: TValue) => void;\n}\n\nclass RadioGroupPresenter<TValue = string> implements IRadioGroupPresenter<TValue> {\n private params?: RadioGroupPresenterParams<TValue> = undefined;\n\n constructor() {\n makeAutoObservable(this);\n }\n\n public init = (params: RadioGroupPresenterParams<TValue>) => {\n this.params = params;\n };\n\n get vm() {\n return {\n items: this.getRadioItems().map(item => RadioItemFormatter.format(item))\n };\n }\n\n public changeValue = (value: TValue) => {\n this.params?.onValueChange?.(value);\n };\n\n private getRadioItems() {\n if (!this.params?.items) {\n return [];\n }\n\n return this.params.items.map(item => RadioItem.create(item));\n }\n}\n\nexport { RadioGroupPresenter, type RadioGroupPresenterParams, type IRadioGroupPresenter };\n"],"names":["RadioGroupPresenter","undefined","params","value","makeAutoObservable","item","RadioItemFormatter","RadioItem"],"mappings":";;;AAiBA,MAAMA;IAGF,aAAc;aAFN,MAAM,GAAuCC;aAM9C,IAAI,GAAG,CAACC;YACX,IAAI,CAAC,MAAM,GAAGA;QAClB;aAQO,WAAW,GAAG,CAACC;YAClB,IAAI,CAAC,MAAM,EAAE,gBAAgBA;QACjC;QAfIC,mBAAmB,IAAI;IAC3B;IAMA,IAAI,KAAK;QACL,OAAO;YACH,OAAO,IAAI,CAAC,aAAa,GAAG,GAAG,CAACC,CAAAA,OAAQC,mBAAmB,MAAM,CAACD;QACtE;IACJ;IAMQ,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OACd,OAAO,EAAE;QAGb,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAACA,CAAAA,OAAQE,UAAU,MAAM,CAACF;IAC1D;AACJ"}
1
+ {"version":3,"file":"RadioGroup/primitives/presenters/RadioGroupPresenter.js","sources":["../../../../src/RadioGroup/primitives/presenters/RadioGroupPresenter.ts"],"sourcesContent":["import { makeAutoObservable } from \"mobx\";\nimport { observableRef } from \"mobx\";\nimport type { RadioGroupVm } from \"../RadioGroupPrimitive.js\";\nimport { RadioItem } from \"~/RadioGroup/domains/RadioItem.js\";\nimport { RadioItemFormatter } from \"~/RadioGroup/domains/RadioItemFormatter.js\";\nimport type { RadioItemParams } from \"~/RadioGroup/domains/RadioItemParams.js\";\n\ninterface RadioGroupPresenterParams<TValue = string> {\n items: RadioItemParams[];\n onValueChange?: (value: TValue) => void;\n}\n\ninterface IRadioGroupPresenter<TValue = string> {\n vm: RadioGroupVm;\n init: (props: RadioGroupPresenterParams<TValue>) => void;\n changeValue: (value: TValue) => void;\n}\n\nclass RadioGroupPresenter<TValue = string> implements IRadioGroupPresenter<TValue> {\n private params?: RadioGroupPresenterParams<TValue> = undefined;\n\n constructor() {\n makeAutoObservable<RadioGroupPresenter<TValue>, \"params\">(this, {\n params: observableRef\n });\n }\n\n public init = (params: RadioGroupPresenterParams<TValue>) => {\n this.params = params;\n };\n\n get vm() {\n return {\n items: this.getRadioItems().map(item => RadioItemFormatter.format(item))\n };\n }\n\n public changeValue = (value: TValue) => {\n this.params?.onValueChange?.(value);\n };\n\n private getRadioItems() {\n if (!this.params?.items) {\n return [];\n }\n\n return this.params.items.map(item => RadioItem.create(item));\n }\n}\n\nexport { RadioGroupPresenter, type RadioGroupPresenterParams, type IRadioGroupPresenter };\n"],"names":["RadioGroupPresenter","undefined","params","value","makeAutoObservable","observableRef","item","RadioItemFormatter","RadioItem"],"mappings":";;;AAkBA,MAAMA;IAGF,aAAc;aAFN,MAAM,GAAuCC;aAQ9C,IAAI,GAAG,CAACC;YACX,IAAI,CAAC,MAAM,GAAGA;QAClB;aAQO,WAAW,GAAG,CAACC;YAClB,IAAI,CAAC,MAAM,EAAE,gBAAgBA;QACjC;QAjBIC,mBAA0D,IAAI,EAAE;YAC5D,QAAQC;QACZ;IACJ;IAMA,IAAI,KAAK;QACL,OAAO;YACH,OAAO,IAAI,CAAC,aAAa,GAAG,GAAG,CAACC,CAAAA,OAAQC,mBAAmB,MAAM,CAACD;QACtE;IACJ;IAMQ,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OACd,OAAO,EAAE;QAGb,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAACA,CAAAA,OAAQE,UAAU,MAAM,CAACF;IAC1D;AACJ"}
@@ -0,0 +1,88 @@
1
+ import react from "react";
2
+ import { describe, expect, it, vi } from "vitest";
3
+ import { RadioGroupPresenter } from "./RadioGroupPresenter.js";
4
+ const createCyclicLabel = ()=>{
5
+ const fiber = {
6
+ tag: 0
7
+ };
8
+ fiber.return = fiber;
9
+ fiber.child = fiber;
10
+ const element = react.createElement("span", null, "Card");
11
+ return {
12
+ ...element,
13
+ _owner: fiber
14
+ };
15
+ };
16
+ describe("RadioGroupPresenter with a React node label", ()=>{
17
+ it("keeps the label by reference and does not overflow the stack", ()=>{
18
+ const label = createCyclicLabel();
19
+ const presenter = new RadioGroupPresenter();
20
+ const init = ()=>{
21
+ presenter.init({
22
+ onValueChange: vi.fn(),
23
+ items: [
24
+ {
25
+ value: "a",
26
+ label
27
+ },
28
+ {
29
+ value: "b",
30
+ label: "Plain"
31
+ }
32
+ ]
33
+ });
34
+ };
35
+ expect(init).not.toThrow();
36
+ expect(presenter.vm.items).toHaveLength(2);
37
+ expect(presenter.vm.items[0].label).toBe(label);
38
+ expect(presenter.vm.items[1].label).toBe("Plain");
39
+ });
40
+ it("still reports a value change", ()=>{
41
+ const onValueChange = vi.fn();
42
+ const label = createCyclicLabel();
43
+ const presenter = new RadioGroupPresenter();
44
+ presenter.init({
45
+ onValueChange,
46
+ items: [
47
+ {
48
+ value: "a",
49
+ label
50
+ }
51
+ ]
52
+ });
53
+ presenter.changeValue("a");
54
+ expect(onValueChange).toHaveBeenCalledWith("a");
55
+ });
56
+ it("recomputes the view model when init is called again", ()=>{
57
+ const first = createCyclicLabel();
58
+ const second = createCyclicLabel();
59
+ const presenter = new RadioGroupPresenter();
60
+ presenter.init({
61
+ items: [
62
+ {
63
+ value: "a",
64
+ label: first
65
+ }
66
+ ]
67
+ });
68
+ presenter.init({
69
+ items: [
70
+ {
71
+ value: "a",
72
+ label: first
73
+ },
74
+ {
75
+ value: "b",
76
+ label: second
77
+ }
78
+ ]
79
+ });
80
+ expect(presenter.vm.items.map((item)=>item.value)).toEqual([
81
+ "a",
82
+ "b"
83
+ ]);
84
+ expect(presenter.vm.items[1].label).toBe(second);
85
+ });
86
+ });
87
+
88
+ //# sourceMappingURL=RadioGroupPresenter.jsxLabel.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroup/primitives/presenters/RadioGroupPresenter.jsxLabel.test.js","sources":["../../../../src/RadioGroup/primitives/presenters/RadioGroupPresenter.jsxLabel.test.ts"],"sourcesContent":["import React from \"react\";\nimport { describe } from \"vitest\";\nimport { expect } from \"vitest\";\nimport { it } from \"vitest\";\nimport { vi } from \"vitest\";\nimport { RadioGroupPresenter } from \"./RadioGroupPresenter.js\";\n\n/*\n * A React element created during a render points at its owner fiber, and a fiber points back at\n * its parent and children. A deep observable walks that whole cycle and overflows the stack.\n */\nconst createCyclicLabel = () => {\n const fiber: Record<string, unknown> = { tag: 0 };\n fiber.return = fiber;\n fiber.child = fiber;\n const element = React.createElement(\"span\", null, \"Card\");\n return { ...element, _owner: fiber };\n};\n\ndescribe(\"RadioGroupPresenter with a React node label\", () => {\n it(\"keeps the label by reference and does not overflow the stack\", () => {\n const label = createCyclicLabel();\n const presenter = new RadioGroupPresenter();\n\n const init = () => {\n presenter.init({\n onValueChange: vi.fn(),\n items: [\n { value: \"a\", label },\n { value: \"b\", label: \"Plain\" }\n ]\n });\n };\n\n expect(init).not.toThrow();\n expect(presenter.vm.items).toHaveLength(2);\n expect(presenter.vm.items[0].label).toBe(label);\n expect(presenter.vm.items[1].label).toBe(\"Plain\");\n });\n\n it(\"still reports a value change\", () => {\n const onValueChange = vi.fn();\n const label = createCyclicLabel();\n const presenter = new RadioGroupPresenter();\n presenter.init({ onValueChange, items: [{ value: \"a\", label }] });\n\n presenter.changeValue(\"a\");\n\n expect(onValueChange).toHaveBeenCalledWith(\"a\");\n });\n\n it(\"recomputes the view model when init is called again\", () => {\n const first = createCyclicLabel();\n const second = createCyclicLabel();\n const presenter = new RadioGroupPresenter();\n presenter.init({ items: [{ value: \"a\", label: first }] });\n presenter.init({\n items: [\n { value: \"a\", label: first },\n { value: \"b\", label: second }\n ]\n });\n\n expect(presenter.vm.items.map(item => item.value)).toEqual([\"a\", \"b\"]);\n expect(presenter.vm.items[1].label).toBe(second);\n });\n});\n"],"names":["createCyclicLabel","fiber","element","React","describe","it","label","presenter","RadioGroupPresenter","init","vi","expect","onValueChange","first","second","item"],"mappings":";;;AAWA,MAAMA,oBAAoB;IACtB,MAAMC,QAAiC;QAAE,KAAK;IAAE;IAChDA,MAAM,MAAM,GAAGA;IACfA,MAAM,KAAK,GAAGA;IACd,MAAMC,UAAUC,MAAAA,aAAmB,CAAC,QAAQ,MAAM;IAClD,OAAO;QAAE,GAAGD,OAAO;QAAE,QAAQD;IAAM;AACvC;AAEAG,SAAS,+CAA+C;IACpDC,GAAG,gEAAgE;QAC/D,MAAMC,QAAQN;QACd,MAAMO,YAAY,IAAIC;QAEtB,MAAMC,OAAO;YACTF,UAAU,IAAI,CAAC;gBACX,eAAeG,GAAG,EAAE;gBACpB,OAAO;oBACH;wBAAE,OAAO;wBAAKJ;oBAAM;oBACpB;wBAAE,OAAO;wBAAK,OAAO;oBAAQ;iBAChC;YACL;QACJ;QAEAK,OAAOF,MAAM,GAAG,CAAC,OAAO;QACxBE,OAAOJ,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC;QACxCI,OAAOJ,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAACD;QACzCK,OAAOJ,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;IAC7C;IAEAF,GAAG,gCAAgC;QAC/B,MAAMO,gBAAgBF,GAAG,EAAE;QAC3B,MAAMJ,QAAQN;QACd,MAAMO,YAAY,IAAIC;QACtBD,UAAU,IAAI,CAAC;YAAEK;YAAe,OAAO;gBAAC;oBAAE,OAAO;oBAAKN;gBAAM;aAAE;QAAC;QAE/DC,UAAU,WAAW,CAAC;QAEtBI,OAAOC,eAAe,oBAAoB,CAAC;IAC/C;IAEAP,GAAG,uDAAuD;QACtD,MAAMQ,QAAQb;QACd,MAAMc,SAASd;QACf,MAAMO,YAAY,IAAIC;QACtBD,UAAU,IAAI,CAAC;YAAE,OAAO;gBAAC;oBAAE,OAAO;oBAAK,OAAOM;gBAAM;aAAE;QAAC;QACvDN,UAAU,IAAI,CAAC;YACX,OAAO;gBACH;oBAAE,OAAO;oBAAK,OAAOM;gBAAM;gBAC3B;oBAAE,OAAO;oBAAK,OAAOC;gBAAO;aAC/B;QACL;QAEAH,OAAOJ,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAACQ,CAAAA,OAAQA,KAAK,KAAK,GAAG,OAAO,CAAC;YAAC;YAAK;SAAI;QACrEJ,OAAOJ,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAACO;IAC7C;AACJ"}
@@ -13,7 +13,21 @@ export interface ScrollPosition {
13
13
  interface ScrollAreaProps extends Omit<React.ComponentProps<typeof ScrollAreaPrimitive.Root>, "onScroll"> {
14
14
  onScrollPositionChange?: (position: ScrollPosition) => void;
15
15
  onScroll?: (position: ScrollPosition) => void;
16
+ /**
17
+ * Classes for the scrolling element itself. Put the height limit here when the area has to grow
18
+ * with its content up to a maximum, instead of filling a parent of a known height.
19
+ */
20
+ viewportClassName?: string;
21
+ /**
22
+ * Native scroll handler for the scrolling element, for callers that need the event itself.
23
+ * `onScroll` reports positions instead.
24
+ */
25
+ onViewportScroll?: React.UIEventHandler<HTMLDivElement>;
26
+ /**
27
+ * Ref to the scrolling element, for callers that scroll it themselves.
28
+ */
29
+ viewportRef?: React.Ref<HTMLDivElement>;
16
30
  }
17
- declare function ScrollArea({ className, children, onScrollPositionChange, onScroll, ...props }: ScrollAreaProps): React.JSX.Element;
18
- declare function ScrollBar({ className, orientation, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>): React.JSX.Element;
31
+ declare function ScrollArea({ className, children, onScrollPositionChange, onScroll, viewportClassName, onViewportScroll, viewportRef: externalViewportRef, type, ...props }: ScrollAreaProps): React.JSX.Element;
32
+ declare function ScrollBar({ className, orientation, onMouseDown, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>): React.JSX.Element;
19
33
  export { ScrollArea, ScrollBar };
@@ -1,8 +1,15 @@
1
1
  import { cn } from "../utils.js";
2
2
  import * as __rspack_external_react from "react";
3
3
  import * as __rspack_external__radix_ui_react_scroll_area_bdec1136 from "@radix-ui/react-scroll-area";
4
- function ScrollArea({ className, children, onScrollPositionChange, onScroll, ...props }) {
4
+ function ScrollArea({ className, children, onScrollPositionChange, onScroll, viewportClassName, onViewportScroll, viewportRef: externalViewportRef, type = "auto", ...props }) {
5
5
  const viewportRef = __rspack_external_react.useRef(null);
6
+ const setViewportRef = __rspack_external_react.useCallback((element)=>{
7
+ viewportRef.current = element;
8
+ if ("function" == typeof externalViewportRef) externalViewportRef(element);
9
+ else if (externalViewportRef) externalViewportRef.current = element;
10
+ }, [
11
+ externalViewportRef
12
+ ]);
6
13
  __rspack_external_react.useEffect(()=>{
7
14
  const viewport = viewportRef.current;
8
15
  if (!viewport || !onScrollPositionChange && !onScroll) return;
@@ -30,19 +37,26 @@ function ScrollArea({ className, children, onScrollPositionChange, onScroll, ...
30
37
  ]);
31
38
  return /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.Root, {
32
39
  "data-slot": "scroll-area",
40
+ type: type,
33
41
  className: cn("relative", className),
34
42
  ...props
35
43
  }, /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.Viewport, {
36
- ref: viewportRef,
44
+ ref: setViewportRef,
37
45
  "data-slot": "scroll-area-viewport",
38
- className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
46
+ onScroll: onViewportScroll,
47
+ className: cn("focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1", viewportClassName)
39
48
  }, children), /*#__PURE__*/ __rspack_external_react.createElement(ScrollBar, null), /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.Corner, null));
40
49
  }
41
- function ScrollBar({ className, orientation = "vertical", ...props }) {
50
+ function ScrollBar({ className, orientation = "vertical", onMouseDown, ...props }) {
51
+ const handleMouseDown = (event)=>{
52
+ onMouseDown?.(event);
53
+ event.preventDefault();
54
+ };
42
55
  return /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.ScrollAreaScrollbar, {
43
56
  "data-slot": "scroll-area-scrollbar",
44
57
  orientation: orientation,
45
- className: cn("flex touch-none transition-colors select-none", "vertical" === orientation && "h-full w-[8px] border-l border-l-transparent", "horizontal" === orientation && "h-[8px] flex-col border-t border-t-transparent", className),
58
+ onMouseDown: handleMouseDown,
59
+ className: cn("flex touch-none transition-colors select-none", "vertical" === orientation && "h-full w-[10px] p-[2px]", "horizontal" === orientation && "h-[10px] flex-col p-[2px]", className),
46
60
  ...props
47
61
  }, /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.ScrollAreaThumb, {
48
62
  "data-slot": "scroll-area-thumb",
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollArea/ScrollArea.js","sources":["../../src/ScrollArea/ScrollArea.tsx"],"sourcesContent":["import * as React from \"react\";\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\nimport { cn } from \"~/utils.js\";\n\nexport interface ScrollPosition {\n top: number;\n left: number;\n scrollTop: number;\n scrollLeft: number;\n scrollHeight: number;\n scrollWidth: number;\n clientHeight: number;\n clientWidth: number;\n}\n\ninterface ScrollAreaProps extends Omit<\n React.ComponentProps<typeof ScrollAreaPrimitive.Root>,\n \"onScroll\"\n> {\n onScrollPositionChange?: (position: ScrollPosition) => void;\n onScroll?: (position: ScrollPosition) => void;\n}\n\nfunction ScrollArea({\n className,\n children,\n onScrollPositionChange,\n onScroll,\n ...props\n}: ScrollAreaProps) {\n const viewportRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport || (!onScrollPositionChange && !onScroll)) {\n return;\n }\n\n // The Viewport component itself is the scrollable element.\n const handleScroll = () => {\n const { scrollTop, scrollLeft, scrollHeight, scrollWidth, clientHeight, clientWidth } =\n viewport;\n\n const position: ScrollPosition = {\n top: scrollHeight > clientHeight ? scrollTop / (scrollHeight - clientHeight) : 0,\n left: scrollWidth > clientWidth ? scrollLeft / (scrollWidth - clientWidth) : 0,\n scrollTop,\n scrollLeft,\n scrollHeight,\n scrollWidth,\n clientHeight,\n clientWidth\n };\n\n onScrollPositionChange?.(position);\n onScroll?.(position);\n };\n\n // Call handleScroll initially to provide initial position.\n handleScroll();\n\n viewport.addEventListener(\"scroll\", handleScroll);\n return () => viewport.removeEventListener(\"scroll\", handleScroll);\n }, [onScrollPositionChange, onScroll]);\n\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n ref={viewportRef}\n data-slot=\"scroll-area-viewport\"\n className=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n \"flex touch-none transition-colors select-none\",\n orientation === \"vertical\" && \"h-full w-[8px] border-l border-l-transparent\",\n orientation === \"horizontal\" && \"h-[8px] flex-col border-t border-t-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-neutral-strong/70 relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n}\n\nexport { ScrollArea, ScrollBar };\n"],"names":["ScrollArea","className","children","onScrollPositionChange","onScroll","props","viewportRef","React","viewport","handleScroll","scrollTop","scrollLeft","scrollHeight","scrollWidth","clientHeight","clientWidth","position","ScrollAreaPrimitive","cn","ScrollBar","orientation"],"mappings":";;;AAuBA,SAASA,WAAW,EAChBC,SAAS,EACTC,QAAQ,EACRC,sBAAsB,EACtBC,QAAQ,EACR,GAAGC,OACW;IACd,MAAMC,cAAcC,wBAAAA,MAAY,CAAiB;IAEjDA,wBAAAA,SAAe,CAAC;QACZ,MAAMC,WAAWF,YAAY,OAAO;QACpC,IAAI,CAACE,YAAa,CAACL,0BAA0B,CAACC,UAC1C;QAIJ,MAAMK,eAAe;YACjB,MAAM,EAAEC,SAAS,EAAEC,UAAU,EAAEC,YAAY,EAAEC,WAAW,EAAEC,YAAY,EAAEC,WAAW,EAAE,GACjFP;YAEJ,MAAMQ,WAA2B;gBAC7B,KAAKJ,eAAeE,eAAeJ,YAAaE,CAAAA,eAAeE,YAAW,IAAK;gBAC/E,MAAMD,cAAcE,cAAcJ,aAAcE,CAAAA,cAAcE,WAAU,IAAK;gBAC7EL;gBACAC;gBACAC;gBACAC;gBACAC;gBACAC;YACJ;YAEAZ,yBAAyBa;YACzBZ,WAAWY;QACf;QAGAP;QAEAD,SAAS,gBAAgB,CAAC,UAAUC;QACpC,OAAO,IAAMD,SAAS,mBAAmB,CAAC,UAAUC;IACxD,GAAG;QAACN;QAAwBC;KAAS;IAErC,OAAO,WAAP,GACI,sCAACa,uDAAAA,IAAwB;QACrB,aAAU;QACV,WAAWC,GAAG,YAAYjB;QACzB,GAAGI,KAAK;qBAET,sCAACY,uDAAAA,QAA4B;QACzB,KAAKX;QACL,aAAU;QACV,WAAU;OAETJ,WAAAA,WAAAA,GAEL,sCAACiB,WAASA,OAAAA,WAAAA,GACV,sCAACF,uDAAAA,MAA0B;AAGvC;AAEA,SAASE,UAAU,EACflB,SAAS,EACTmB,cAAc,UAAU,EACxB,GAAGf,OACgE;IACnE,OAAO,WAAP,GACI,sCAACY,uDAAAA,mBAAuC;QACpC,aAAU;QACV,aAAaG;QACb,WAAWF,GACP,iDACAE,AAAgB,eAAhBA,eAA8B,gDAC9BA,AAAgB,iBAAhBA,eAAgC,kDAChCnB;QAEH,GAAGI,KAAK;qBAET,sCAACY,uDAAAA,eAAmC;QAChC,aAAU;QACV,WAAU;;AAI1B"}
1
+ {"version":3,"file":"ScrollArea/ScrollArea.js","sources":["../../src/ScrollArea/ScrollArea.tsx"],"sourcesContent":["import * as React from \"react\";\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\nimport { cn } from \"~/utils.js\";\n\nexport interface ScrollPosition {\n top: number;\n left: number;\n scrollTop: number;\n scrollLeft: number;\n scrollHeight: number;\n scrollWidth: number;\n clientHeight: number;\n clientWidth: number;\n}\n\ninterface ScrollAreaProps extends Omit<\n React.ComponentProps<typeof ScrollAreaPrimitive.Root>,\n \"onScroll\"\n> {\n onScrollPositionChange?: (position: ScrollPosition) => void;\n onScroll?: (position: ScrollPosition) => void;\n /**\n * Classes for the scrolling element itself. Put the height limit here when the area has to grow\n * with its content up to a maximum, instead of filling a parent of a known height.\n */\n viewportClassName?: string;\n /**\n * Native scroll handler for the scrolling element, for callers that need the event itself.\n * `onScroll` reports positions instead.\n */\n onViewportScroll?: React.UIEventHandler<HTMLDivElement>;\n /**\n * Ref to the scrolling element, for callers that scroll it themselves.\n */\n viewportRef?: React.Ref<HTMLDivElement>;\n}\n\nfunction ScrollArea({\n className,\n children,\n onScrollPositionChange,\n onScroll,\n viewportClassName,\n onViewportScroll,\n viewportRef: externalViewportRef,\n /*\n * Radix would only show the scrollbar once the pointer is inside. Showing it whenever there is\n * more content is the same rule the rest of the admin follows, a Select included.\n */\n type = \"auto\",\n ...props\n}: ScrollAreaProps) {\n const viewportRef = React.useRef<HTMLDivElement | null>(null);\n\n // The internal ref drives the scroll listener below; a caller's ref gets the same element.\n const setViewportRef = React.useCallback(\n (element: HTMLDivElement | null) => {\n viewportRef.current = element;\n if (typeof externalViewportRef === \"function\") {\n externalViewportRef(element);\n } else if (externalViewportRef) {\n (externalViewportRef as React.MutableRefObject<HTMLDivElement | null>).current =\n element;\n }\n },\n [externalViewportRef]\n );\n\n React.useEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport || (!onScrollPositionChange && !onScroll)) {\n return;\n }\n\n // The Viewport component itself is the scrollable element.\n const handleScroll = () => {\n const { scrollTop, scrollLeft, scrollHeight, scrollWidth, clientHeight, clientWidth } =\n viewport;\n\n const position: ScrollPosition = {\n top: scrollHeight > clientHeight ? scrollTop / (scrollHeight - clientHeight) : 0,\n left: scrollWidth > clientWidth ? scrollLeft / (scrollWidth - clientWidth) : 0,\n scrollTop,\n scrollLeft,\n scrollHeight,\n scrollWidth,\n clientHeight,\n clientWidth\n };\n\n onScrollPositionChange?.(position);\n onScroll?.(position);\n };\n\n // Call handleScroll initially to provide initial position.\n handleScroll();\n\n viewport.addEventListener(\"scroll\", handleScroll);\n return () => viewport.removeEventListener(\"scroll\", handleScroll);\n }, [onScrollPositionChange, onScroll]);\n\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n type={type}\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n ref={setViewportRef}\n data-slot=\"scroll-area-viewport\"\n onScroll={onViewportScroll}\n className={cn(\n \"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\",\n viewportClassName\n )}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n onMouseDown,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n const handleMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n onMouseDown?.(event);\n\n /*\n * Grabbing a scrollbar must not move focus. An autocomplete closes its list the moment its\n * input blurs, so without this, dragging the thumb dismisses the list under the pointer.\n */\n event.preventDefault();\n };\n\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n onMouseDown={handleMouseDown}\n className={cn(\n \"flex touch-none transition-colors select-none\",\n orientation === \"vertical\" && \"h-full w-[10px] p-[2px]\",\n orientation === \"horizontal\" && \"h-[10px] flex-col p-[2px]\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-neutral-strong/70 relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n}\n\nexport { ScrollArea, ScrollBar };\n"],"names":["ScrollArea","className","children","onScrollPositionChange","onScroll","viewportClassName","onViewportScroll","externalViewportRef","type","props","viewportRef","React","setViewportRef","element","viewport","handleScroll","scrollTop","scrollLeft","scrollHeight","scrollWidth","clientHeight","clientWidth","position","ScrollAreaPrimitive","cn","ScrollBar","orientation","onMouseDown","handleMouseDown","event"],"mappings":";;;AAqCA,SAASA,WAAW,EAChBC,SAAS,EACTC,QAAQ,EACRC,sBAAsB,EACtBC,QAAQ,EACRC,iBAAiB,EACjBC,gBAAgB,EAChB,aAAaC,mBAAmB,EAKhCC,OAAO,MAAM,EACb,GAAGC,OACW;IACd,MAAMC,cAAcC,wBAAAA,MAAY,CAAwB;IAGxD,MAAMC,iBAAiBD,wBAAAA,WAAiB,CACpC,CAACE;QACGH,YAAY,OAAO,GAAGG;QACtB,IAAI,AAA+B,cAA/B,OAAON,qBACPA,oBAAoBM;aACjB,IAAIN,qBACNA,oBAAsE,OAAO,GAC1EM;IAEZ,GACA;QAACN;KAAoB;IAGzBI,wBAAAA,SAAe,CAAC;QACZ,MAAMG,WAAWJ,YAAY,OAAO;QACpC,IAAI,CAACI,YAAa,CAACX,0BAA0B,CAACC,UAC1C;QAIJ,MAAMW,eAAe;YACjB,MAAM,EAAEC,SAAS,EAAEC,UAAU,EAAEC,YAAY,EAAEC,WAAW,EAAEC,YAAY,EAAEC,WAAW,EAAE,GACjFP;YAEJ,MAAMQ,WAA2B;gBAC7B,KAAKJ,eAAeE,eAAeJ,YAAaE,CAAAA,eAAeE,YAAW,IAAK;gBAC/E,MAAMD,cAAcE,cAAcJ,aAAcE,CAAAA,cAAcE,WAAU,IAAK;gBAC7EL;gBACAC;gBACAC;gBACAC;gBACAC;gBACAC;YACJ;YAEAlB,yBAAyBmB;YACzBlB,WAAWkB;QACf;QAGAP;QAEAD,SAAS,gBAAgB,CAAC,UAAUC;QACpC,OAAO,IAAMD,SAAS,mBAAmB,CAAC,UAAUC;IACxD,GAAG;QAACZ;QAAwBC;KAAS;IAErC,OAAO,WAAP,GACI,sCAACmB,uDAAAA,IAAwB;QACrB,aAAU;QACV,MAAMf;QACN,WAAWgB,GAAG,YAAYvB;QACzB,GAAGQ,KAAK;qBAET,sCAACc,uDAAAA,QAA4B;QACzB,KAAKX;QACL,aAAU;QACV,UAAUN;QACV,WAAWkB,GACP,sJACAnB;OAGHH,WAAAA,WAAAA,GAEL,sCAACuB,WAASA,OAAAA,WAAAA,GACV,sCAACF,uDAAAA,MAA0B;AAGvC;AAEA,SAASE,UAAU,EACfxB,SAAS,EACTyB,cAAc,UAAU,EACxBC,WAAW,EACX,GAAGlB,OACgE;IACnE,MAAMmB,kBAAkB,CAACC;QACrBF,cAAcE;QAMdA,MAAM,cAAc;IACxB;IAEA,OAAO,WAAP,GACI,sCAACN,uDAAAA,mBAAuC;QACpC,aAAU;QACV,aAAaG;QACb,aAAaE;QACb,WAAWJ,GACP,iDACAE,AAAgB,eAAhBA,eAA8B,2BAC9BA,AAAgB,iBAAhBA,eAAgC,6BAChCzB;QAEH,GAAGQ,KAAK;qBAET,sCAACc,uDAAAA,eAAmC;QAChC,aAAU;QACV,WAAU;;AAI1B"}
@@ -1,22 +1,20 @@
1
1
  import { Select } from "radix-ui";
2
2
  import { cn } from "../../../utils.js";
3
- import { SelectScrollUpButton } from "./SelectScrollUpButton.js";
4
- import { SelectScrollDownButton } from "./SelectScrollDownButton.js";
5
3
  import * as __rspack_external_react from "react";
6
4
  const SelectContent = ({ className, children, ...props })=>/*#__PURE__*/ __rspack_external_react.createElement(Select.Portal, null, /*#__PURE__*/ __rspack_external_react.createElement(Select.Content, {
7
5
  className: cn([
8
- "relative z-popover max-h-[250px] min-w-56 shadow-lg py-sm overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong",
6
+ "relative z-popover max-h-[250px] min-w-56 shadow-lg overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong",
9
7
  "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
10
8
  "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1"
11
9
  ], className),
12
10
  position: "popper",
13
11
  ...props
14
- }, /*#__PURE__*/ __rspack_external_react.createElement(SelectScrollUpButton, null), /*#__PURE__*/ __rspack_external_react.createElement(Select.Viewport, {
12
+ }, /*#__PURE__*/ __rspack_external_react.createElement(Select.Viewport, {
15
13
  className: cn([
16
- "py-xs",
14
+ "py-sm",
17
15
  "h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)"
18
16
  ])
19
- }, children), /*#__PURE__*/ __rspack_external_react.createElement(SelectScrollDownButton, null)));
17
+ }, children)));
20
18
  export { SelectContent };
21
19
 
22
20
  //# sourceMappingURL=SelectContent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Select/primitives/components/SelectContent.js","sources":["../../../../src/Select/primitives/components/SelectContent.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Select as SelectPrimitives } from \"radix-ui\";\nimport { cn } from \"~/utils.js\";\nimport { SelectScrollUpButton } from \"./SelectScrollUpButton.js\";\nimport { SelectScrollDownButton } from \"./SelectScrollDownButton.js\";\n\ntype SelectContentProps = SelectPrimitives.SelectContentProps;\n\nconst SelectContent = ({ className, children, ...props }: SelectContentProps) => (\n <SelectPrimitives.Portal>\n <SelectPrimitives.Content\n className={cn(\n [\n \"relative z-popover max-h-[250px] min-w-56 shadow-lg py-sm overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\"\n ],\n className\n )}\n position={\"popper\"}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitives.Viewport\n className={cn([\n \"py-xs\",\n \"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)\"\n ])}\n >\n {children}\n </SelectPrimitives.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitives.Content>\n </SelectPrimitives.Portal>\n);\n\nexport { SelectContent, type SelectContentProps };\n"],"names":["SelectContent","className","children","props","SelectPrimitives","cn","SelectScrollUpButton","SelectScrollDownButton"],"mappings":";;;;;AAQA,MAAMA,gBAAgB,CAAC,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,OAA2B,iBACxE,sCAACC,OAAAA,MAAuB,sBACpB,sCAACA,OAAAA,OAAwB;QACrB,WAAWC,GACP;YACI;YACA;YACA;SACH,EACDJ;QAEJ,UAAU;QACT,GAAGE,KAAK;qBAET,sCAACG,sBAAoBA,OAAAA,WAAAA,GACrB,sCAACF,OAAAA,QAAyB;QACtB,WAAWC,GAAG;YACV;YACA;SACH;OAEAH,WAAAA,WAAAA,GAEL,sCAACK,wBAAsBA"}
1
+ {"version":3,"file":"Select/primitives/components/SelectContent.js","sources":["../../../../src/Select/primitives/components/SelectContent.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Select as SelectPrimitives } from \"radix-ui\";\nimport { cn } from \"~/utils.js\";\n\ntype SelectContentProps = SelectPrimitives.SelectContentProps;\n\nconst SelectContent = ({ className, children, ...props }: SelectContentProps) => (\n <SelectPrimitives.Portal>\n <SelectPrimitives.Content\n className={cn(\n [\n \"relative z-popover max-h-[250px] min-w-56 shadow-lg overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\"\n ],\n className\n )}\n position={\"popper\"}\n {...props}\n >\n {/* Two things keep this scrollbar in line with the one in the autocomplete popovers.\n No scroll buttons, because they come and go with the scroll position, taking the\n viewport height and the size of the thumb with them. And the padding on the\n viewport rather than around it, so the scrollbar runs the full height of the list. */}\n <SelectPrimitives.Viewport\n className={cn([\n \"py-sm\",\n \"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)\"\n ])}\n >\n {children}\n </SelectPrimitives.Viewport>\n </SelectPrimitives.Content>\n </SelectPrimitives.Portal>\n);\n\nexport { SelectContent, type SelectContentProps };\n"],"names":["SelectContent","className","children","props","SelectPrimitives","cn"],"mappings":";;;AAMA,MAAMA,gBAAgB,CAAC,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,OAA2B,iBACxE,sCAACC,OAAAA,MAAuB,sBACpB,sCAACA,OAAAA,OAAwB;QACrB,WAAWC,GACP;YACI;YACA;YACA;SACH,EACDJ;QAEJ,UAAU;QACT,GAAGE,KAAK;qBAMT,sCAACC,OAAAA,QAAyB;QACtB,WAAWC,GAAG;YACV;YACA;SACH;OAEAH"}
@@ -1,8 +1,8 @@
1
1
  import React from "react";
2
2
  import type { SwitchPrimitiveProps } from "./primitives/index.js";
3
- import type { FormComponentProps } from "../FormComponent/index.js";
4
- type SwitchProps = SwitchPrimitiveProps & FormComponentProps;
5
- declare const DecoratableSwitch: ({ note, validation, ...props }: SwitchProps) => React.JSX.Element;
3
+ import { type FormComponentProps } from "../FormComponent/index.js";
4
+ type SwitchProps = Omit<SwitchPrimitiveProps, "label"> & FormComponentProps;
5
+ declare const DecoratableSwitch: ({ label, description, hint, note, required, disabled, validation, ...props }: SwitchProps) => React.JSX.Element;
6
6
  declare const Switch: typeof DecoratableSwitch & {
7
7
  original: typeof DecoratableSwitch;
8
8
  originalName: string;
@@ -22,4 +22,4 @@ declare const Switch: typeof DecoratableSwitch & {
22
22
  displayName: string;
23
23
  }>) => (props: unknown) => React.JSX.Element;
24
24
  };
25
- export { Switch };
25
+ export { Switch, type SwitchProps };
package/Switch/Switch.js CHANGED
@@ -1,24 +1,38 @@
1
1
  import react, { useMemo } from "react";
2
- import { makeDecoratable } from "../utils.js";
2
+ import { generateId, makeDecoratable } from "../utils.js";
3
3
  import { SwitchPrimitive } from "./primitives/index.js";
4
- import { FormComponentErrorMessage, FormComponentNote } from "../FormComponent/index.js";
5
- const DecoratableSwitch = ({ note, validation, ...props })=>{
4
+ import { FormComponentDescription, FormComponentErrorMessage, FormComponentLabel, FormComponentNote } from "../FormComponent/index.js";
5
+ const DecoratableSwitch = ({ label, description, hint, note, required, disabled, validation, ...props })=>{
6
6
  const { isValid: validationIsValid, message: validationMessage } = validation || {};
7
+ const id = useMemo(()=>generateId(props.id), [
8
+ props.id
9
+ ]);
7
10
  const invalid = useMemo(()=>false === validationIsValid, [
8
11
  validationIsValid
9
12
  ]);
10
13
  return /*#__PURE__*/ react.createElement("div", {
11
14
  className: "w-full"
12
- }, /*#__PURE__*/ react.createElement(SwitchPrimitive, {
15
+ }, /*#__PURE__*/ react.createElement(FormComponentLabel, {
16
+ htmlFor: id,
17
+ text: label,
18
+ required: required,
19
+ disabled: disabled,
20
+ invalid: invalid,
21
+ hint: hint
22
+ }), /*#__PURE__*/ react.createElement(FormComponentDescription, {
23
+ text: description,
24
+ disabled: disabled
25
+ }), /*#__PURE__*/ react.createElement(SwitchPrimitive, {
13
26
  ...props,
14
- disabled: props.disabled
27
+ id: id,
28
+ disabled: disabled
15
29
  }), /*#__PURE__*/ react.createElement(FormComponentErrorMessage, {
16
30
  text: validationMessage,
17
31
  invalid: invalid,
18
- disabled: props.disabled
32
+ disabled: disabled
19
33
  }), /*#__PURE__*/ react.createElement(FormComponentNote, {
20
34
  text: note,
21
- disabled: props.disabled
35
+ disabled: disabled
22
36
  }));
23
37
  };
24
38
  const Switch = makeDecoratable("Switch", DecoratableSwitch);
@@ -1 +1 @@
1
- {"version":3,"file":"Switch/Switch.js","sources":["../../src/Switch/Switch.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { makeDecoratable } from \"~/utils.js\";\nimport type { SwitchPrimitiveProps } from \"./primitives/index.js\";\nimport { SwitchPrimitive } from \"./primitives/index.js\";\nimport type { FormComponentProps } from \"~/FormComponent/index.js\";\nimport { FormComponentErrorMessage, FormComponentNote } from \"~/FormComponent/index.js\";\n\ntype SwitchProps = SwitchPrimitiveProps & FormComponentProps;\n\nconst DecoratableSwitch = ({ note, validation, ...props }: SwitchProps) => {\n const { isValid: validationIsValid, message: validationMessage } = validation || {};\n const invalid = useMemo(() => validationIsValid === false, [validationIsValid]);\n\n return (\n <div className={\"w-full\"}>\n <SwitchPrimitive {...props} disabled={props.disabled} />\n <FormComponentErrorMessage\n text={validationMessage}\n invalid={invalid}\n disabled={props.disabled}\n />\n <FormComponentNote text={note} disabled={props.disabled} />\n </div>\n );\n};\n\nconst Switch = makeDecoratable(\"Switch\", DecoratableSwitch);\n\nexport { Switch };\n"],"names":["DecoratableSwitch","note","validation","props","validationIsValid","validationMessage","invalid","useMemo","SwitchPrimitive","FormComponentErrorMessage","FormComponentNote","Switch","makeDecoratable"],"mappings":";;;;AASA,MAAMA,oBAAoB,CAAC,EAAEC,IAAI,EAAEC,UAAU,EAAE,GAAGC,OAAoB;IAClE,MAAM,EAAE,SAASC,iBAAiB,EAAE,SAASC,iBAAiB,EAAE,GAAGH,cAAc,CAAC;IAClF,MAAMI,UAAUC,QAAQ,IAAMH,AAAsB,UAAtBA,mBAA6B;QAACA;KAAkB;IAE9E,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACI,iBAAeA;QAAE,GAAGL,KAAK;QAAE,UAAUA,MAAM,QAAQ;sBACpD,oBAACM,2BAAyBA;QACtB,MAAMJ;QACN,SAASC;QACT,UAAUH,MAAM,QAAQ;sBAE5B,oBAACO,mBAAiBA;QAAC,MAAMT;QAAM,UAAUE,MAAM,QAAQ;;AAGnE;AAEA,MAAMQ,SAASC,gBAAgB,UAAUZ"}
1
+ {"version":3,"file":"Switch/Switch.js","sources":["../../src/Switch/Switch.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { generateId, makeDecoratable } from \"~/utils.js\";\nimport type { SwitchPrimitiveProps } from \"./primitives/index.js\";\nimport { SwitchPrimitive } from \"./primitives/index.js\";\nimport {\n FormComponentDescription,\n FormComponentErrorMessage,\n FormComponentLabel,\n FormComponentNote,\n type FormComponentProps\n} from \"~/FormComponent/index.js\";\n\ntype SwitchProps = Omit<SwitchPrimitiveProps, \"label\"> & FormComponentProps;\n\nconst DecoratableSwitch = ({\n label,\n description,\n hint,\n note,\n required,\n disabled,\n validation,\n ...props\n}: SwitchProps) => {\n const { isValid: validationIsValid, message: validationMessage } = validation || {};\n const id = useMemo(() => generateId(props.id), [props.id]);\n const invalid = useMemo(() => validationIsValid === false, [validationIsValid]);\n\n return (\n <div className={\"w-full\"}>\n <FormComponentLabel\n htmlFor={id}\n text={label}\n required={required}\n disabled={disabled}\n invalid={invalid}\n hint={hint}\n />\n <FormComponentDescription text={description} disabled={disabled} />\n <SwitchPrimitive {...props} id={id} disabled={disabled} />\n <FormComponentErrorMessage\n text={validationMessage}\n invalid={invalid}\n disabled={disabled}\n />\n <FormComponentNote text={note} disabled={disabled} />\n </div>\n );\n};\n\nconst Switch = makeDecoratable(\"Switch\", DecoratableSwitch);\n\nexport { Switch, type SwitchProps };\n"],"names":["DecoratableSwitch","label","description","hint","note","required","disabled","validation","props","validationIsValid","validationMessage","id","useMemo","generateId","invalid","FormComponentLabel","FormComponentDescription","SwitchPrimitive","FormComponentErrorMessage","FormComponentNote","Switch","makeDecoratable"],"mappings":";;;;AAcA,MAAMA,oBAAoB,CAAC,EACvBC,KAAK,EACLC,WAAW,EACXC,IAAI,EACJC,IAAI,EACJC,QAAQ,EACRC,QAAQ,EACRC,UAAU,EACV,GAAGC,OACO;IACV,MAAM,EAAE,SAASC,iBAAiB,EAAE,SAASC,iBAAiB,EAAE,GAAGH,cAAc,CAAC;IAClF,MAAMI,KAAKC,QAAQ,IAAMC,WAAWL,MAAM,EAAE,GAAG;QAACA,MAAM,EAAE;KAAC;IACzD,MAAMM,UAAUF,QAAQ,IAAMH,AAAsB,UAAtBA,mBAA6B;QAACA;KAAkB;IAE9E,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACM,oBAAkBA;QACf,SAASJ;QACT,MAAMV;QACN,UAAUI;QACV,UAAUC;QACV,SAASQ;QACT,MAAMX;sBAEV,oBAACa,0BAAwBA;QAAC,MAAMd;QAAa,UAAUI;sBACvD,oBAACW,iBAAeA;QAAE,GAAGT,KAAK;QAAE,IAAIG;QAAI,UAAUL;sBAC9C,oBAACY,2BAAyBA;QACtB,MAAMR;QACN,SAASI;QACT,UAAUR;sBAEd,oBAACa,mBAAiBA;QAAC,MAAMf;QAAM,UAAUE;;AAGrD;AAEA,MAAMc,SAASC,gBAAgB,UAAUrB"}
@@ -1,7 +1,7 @@
1
1
  import type React from "react";
2
2
  export interface SwitchItemDto {
3
3
  id?: string;
4
- label: React.ReactNode;
4
+ label?: React.ReactNode;
5
5
  value?: number | string | boolean;
6
6
  checked?: boolean;
7
7
  disabled?: boolean;
@@ -18,7 +18,7 @@ const SwitchRenderer = ({ id, label, changeChecked, description, className, labe
18
18
  className: cn(switchVariants({
19
19
  labelPosition
20
20
  }), className)
21
- }, /*#__PURE__*/ __rspack_external_react.createElement(Label, {
21
+ }, label && /*#__PURE__*/ __rspack_external_react.createElement(Label, {
22
22
  htmlFor: id,
23
23
  text: label,
24
24
  disabled: disabled,
@@ -30,10 +30,11 @@ const SwitchRenderer = ({ id, label, changeChecked, description, className, labe
30
30
  id: id,
31
31
  checked: checked,
32
32
  className: cn([
33
- "peer inline-flex h-md w-[26px] mt-xxs shrink-0 cursor-pointer items-center rounded-xxl border-sm transition-colors",
33
+ "peer inline-flex h-md w-[26px] shrink-0 cursor-pointer items-center rounded-xxl border-sm transition-colors",
34
34
  "border-transparent data-[state=checked]:bg-secondary data-[state=unchecked]:bg-neutral-strong",
35
35
  "focus-visible:outline-none focus-visible:border-success focus-visible:ring-lg focus-visible:ring-primary-dimmed",
36
- "disabled:cursor-not-allowed disabled:bg-neutral-muted disabled:data-[state=checked]:bg-neutral-muted"
36
+ "disabled:cursor-not-allowed disabled:bg-neutral-muted disabled:data-[state=checked]:bg-neutral-muted",
37
+ label && "mt-xxs"
37
38
  ]),
38
39
  disabled: disabled,
39
40
  onCheckedChange: changeChecked
@@ -1 +1 @@
1
- {"version":3,"file":"Switch/primitives/SwitchPrimitive.js","sources":["../../../src/Switch/primitives/SwitchPrimitive.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Switch as SwitchPrimitives } from \"radix-ui\";\nimport { cn, cva, makeDecoratable, type VariantProps } from \"~/utils.js\";\nimport { Label } from \"~/Label/index.js\";\nimport { useSwitch } from \"./useSwitch.js\";\nimport type { SwitchItemDto, SwitchItemFormatted } from \"../domains/index.js\";\n\n/**\n * Switch Renderer\n */\n\nconst switchVariants = cva(\"inline-flex items-start space-x-sm\", {\n variants: {\n labelPosition: {\n start: \"\",\n end: \"flex-row-reverse space-x-sm-extra space-x-reverse\"\n }\n },\n defaultVariants: {\n labelPosition: \"start\"\n }\n});\n\ntype SwitchPrimitiveProps = Omit<\n SwitchPrimitives.SwitchProps,\n \"defaultChecked\" | \"onCheckedChange\" | \"onChange\"\n> &\n VariantProps<typeof switchVariants> &\n SwitchItemDto & {\n onChange?: (checked: boolean) => void;\n };\n\ntype SwitchPrimitivVm = {\n item?: SwitchItemFormatted;\n};\n\ntype SwitchRendererProps = Omit<SwitchPrimitiveProps, \"onCheckedChange\"> &\n NonNullable<SwitchPrimitivVm[\"item\"]> & {\n changeChecked: (checked: boolean) => void;\n description?: React.ReactNode;\n };\n\nconst SwitchRenderer = ({\n id,\n label,\n changeChecked,\n description,\n className,\n labelPosition,\n disabled,\n required,\n checked\n}: SwitchRendererProps) => {\n return (\n <div className={cn(switchVariants({ labelPosition }), className)}>\n <Label\n htmlFor={id}\n text={label}\n disabled={disabled}\n required={required}\n hint={description}\n weight={\"light\"}\n className={\"text-md\"}\n />\n <SwitchPrimitives.Root\n id={id}\n checked={checked}\n className={cn([\n \"peer inline-flex h-md w-[26px] mt-xxs shrink-0 cursor-pointer items-center rounded-xxl border-sm transition-colors\",\n \"border-transparent data-[state=checked]:bg-secondary data-[state=unchecked]:bg-neutral-strong\",\n \"focus-visible:outline-none focus-visible:border-success focus-visible:ring-lg focus-visible:ring-primary-dimmed\",\n \"disabled:cursor-not-allowed disabled:bg-neutral-muted disabled:data-[state=checked]:bg-neutral-muted\"\n ])}\n disabled={disabled}\n onCheckedChange={changeChecked}\n >\n <SwitchPrimitives.Thumb\n className={cn(\n \"pointer-events-none block h-sm-plus w-sm-plus rounded-xxl bg-neutral-base shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-sm-extra data-[state=unchecked]:translate-x-xxs\"\n )}\n />\n </SwitchPrimitives.Root>\n </div>\n );\n};\n\n/**\n * Switch\n */\nconst DecoratableSwitchPrimitive = (props: SwitchPrimitiveProps) => {\n const { vm, changeChecked } = useSwitch(props);\n\n if (!vm.item) {\n return null;\n }\n\n return <SwitchRenderer {...props} {...vm.item} changeChecked={changeChecked} />;\n};\nconst SwitchPrimitive = makeDecoratable(\"SwitchPrimitive\", DecoratableSwitchPrimitive);\n\nexport { SwitchPrimitive, type SwitchPrimitiveProps, type SwitchPrimitivVm };\n"],"names":["switchVariants","cva","SwitchRenderer","id","label","changeChecked","description","className","labelPosition","disabled","required","checked","cn","Label","SwitchPrimitives","DecoratableSwitchPrimitive","props","vm","useSwitch","SwitchPrimitive","makeDecoratable"],"mappings":";;;;;AAWA,MAAMA,iBAAiBC,IAAI,sCAAsC;IAC7D,UAAU;QACN,eAAe;YACX,OAAO;YACP,KAAK;QACT;IACJ;IACA,iBAAiB;QACb,eAAe;IACnB;AACJ;AAqBA,MAAMC,iBAAiB,CAAC,EACpBC,EAAE,EACFC,KAAK,EACLC,aAAa,EACbC,WAAW,EACXC,SAAS,EACTC,aAAa,EACbC,QAAQ,EACRC,QAAQ,EACRC,OAAO,EACW,GACX,WAAP,GACI,sCAAC;QAAI,WAAWC,GAAGZ,eAAe;YAAEQ;QAAc,IAAID;qBAClD,sCAACM,OAAKA;QACF,SAASV;QACT,MAAMC;QACN,UAAUK;QACV,UAAUC;QACV,MAAMJ;QACN,QAAQ;QACR,WAAW;sBAEf,sCAACQ,OAAAA,IAAqB;QAClB,IAAIX;QACJ,SAASQ;QACT,WAAWC,GAAG;YACV;YACA;YACA;YACA;SACH;QACD,UAAUH;QACV,iBAAiBJ;qBAEjB,sCAACS,OAAAA,KAAsB;QACnB,WAAWF,GACP;;AAWxB,MAAMG,6BAA6B,CAACC;IAChC,MAAM,EAAEC,EAAE,EAAEZ,aAAa,EAAE,GAAGa,UAAUF;IAExC,IAAI,CAACC,GAAG,IAAI,EACR,OAAO;IAGX,OAAO,WAAP,GAAO,sCAACf,gBAAcA;QAAE,GAAGc,KAAK;QAAG,GAAGC,GAAG,IAAI;QAAE,eAAeZ;;AAClE;AACA,MAAMc,kBAAkBC,gBAAgB,mBAAmBL"}
1
+ {"version":3,"file":"Switch/primitives/SwitchPrimitive.js","sources":["../../../src/Switch/primitives/SwitchPrimitive.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Switch as SwitchPrimitives } from \"radix-ui\";\nimport { cn, cva, makeDecoratable, type VariantProps } from \"~/utils.js\";\nimport { Label } from \"~/Label/index.js\";\nimport { useSwitch } from \"./useSwitch.js\";\nimport type { SwitchItemDto, SwitchItemFormatted } from \"../domains/index.js\";\n\n/**\n * Switch Renderer\n */\n\nconst switchVariants = cva(\"inline-flex items-start space-x-sm\", {\n variants: {\n labelPosition: {\n start: \"\",\n end: \"flex-row-reverse space-x-sm-extra space-x-reverse\"\n }\n },\n defaultVariants: {\n labelPosition: \"start\"\n }\n});\n\ntype SwitchPrimitiveProps = Omit<\n SwitchPrimitives.SwitchProps,\n \"defaultChecked\" | \"onCheckedChange\" | \"onChange\"\n> &\n VariantProps<typeof switchVariants> &\n SwitchItemDto & {\n onChange?: (checked: boolean) => void;\n };\n\ntype SwitchPrimitivVm = {\n item?: SwitchItemFormatted;\n};\n\ntype SwitchRendererProps = Omit<SwitchPrimitiveProps, \"onCheckedChange\"> &\n NonNullable<SwitchPrimitivVm[\"item\"]> & {\n changeChecked: (checked: boolean) => void;\n description?: React.ReactNode;\n };\n\nconst SwitchRenderer = ({\n id,\n label,\n changeChecked,\n description,\n className,\n labelPosition,\n disabled,\n required,\n checked\n}: SwitchRendererProps) => {\n return (\n <div className={cn(switchVariants({ labelPosition }), className)}>\n {label && (\n <Label\n htmlFor={id}\n text={label}\n disabled={disabled}\n required={required}\n hint={description}\n weight={\"light\"}\n className={\"text-md\"}\n />\n )}\n <SwitchPrimitives.Root\n id={id}\n checked={checked}\n className={cn([\n \"peer inline-flex h-md w-[26px] shrink-0 cursor-pointer items-center rounded-xxl border-sm transition-colors\",\n \"border-transparent data-[state=checked]:bg-secondary data-[state=unchecked]:bg-neutral-strong\",\n \"focus-visible:outline-none focus-visible:border-success focus-visible:ring-lg focus-visible:ring-primary-dimmed\",\n \"disabled:cursor-not-allowed disabled:bg-neutral-muted disabled:data-[state=checked]:bg-neutral-muted\",\n // Nudges the switch down to line up with the inline label's text.\n label && \"mt-xxs\"\n ])}\n disabled={disabled}\n onCheckedChange={changeChecked}\n >\n <SwitchPrimitives.Thumb\n className={cn(\n \"pointer-events-none block h-sm-plus w-sm-plus rounded-xxl bg-neutral-base shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-sm-extra data-[state=unchecked]:translate-x-xxs\"\n )}\n />\n </SwitchPrimitives.Root>\n </div>\n );\n};\n\n/**\n * Switch\n */\nconst DecoratableSwitchPrimitive = (props: SwitchPrimitiveProps) => {\n const { vm, changeChecked } = useSwitch(props);\n\n if (!vm.item) {\n return null;\n }\n\n return <SwitchRenderer {...props} {...vm.item} changeChecked={changeChecked} />;\n};\nconst SwitchPrimitive = makeDecoratable(\"SwitchPrimitive\", DecoratableSwitchPrimitive);\n\nexport { SwitchPrimitive, type SwitchPrimitiveProps, type SwitchPrimitivVm };\n"],"names":["switchVariants","cva","SwitchRenderer","id","label","changeChecked","description","className","labelPosition","disabled","required","checked","cn","Label","SwitchPrimitives","DecoratableSwitchPrimitive","props","vm","useSwitch","SwitchPrimitive","makeDecoratable"],"mappings":";;;;;AAWA,MAAMA,iBAAiBC,IAAI,sCAAsC;IAC7D,UAAU;QACN,eAAe;YACX,OAAO;YACP,KAAK;QACT;IACJ;IACA,iBAAiB;QACb,eAAe;IACnB;AACJ;AAqBA,MAAMC,iBAAiB,CAAC,EACpBC,EAAE,EACFC,KAAK,EACLC,aAAa,EACbC,WAAW,EACXC,SAAS,EACTC,aAAa,EACbC,QAAQ,EACRC,QAAQ,EACRC,OAAO,EACW,GACX,WAAP,GACI,sCAAC;QAAI,WAAWC,GAAGZ,eAAe;YAAEQ;QAAc,IAAID;OACjDH,SAAS,WAATA,GACG,sCAACS,OAAKA;QACF,SAASV;QACT,MAAMC;QACN,UAAUK;QACV,UAAUC;QACV,MAAMJ;QACN,QAAQ;QACR,WAAW;sBAGnB,sCAACQ,OAAAA,IAAqB;QAClB,IAAIX;QACJ,SAASQ;QACT,WAAWC,GAAG;YACV;YACA;YACA;YACA;YAEAR,SAAS;SACZ;QACD,UAAUK;QACV,iBAAiBJ;qBAEjB,sCAACS,OAAAA,KAAsB;QACnB,WAAWF,GACP;;AAWxB,MAAMG,6BAA6B,CAACC;IAChC,MAAM,EAAEC,EAAE,EAAEZ,aAAa,EAAE,GAAGa,UAAUF;IAExC,IAAI,CAACC,GAAG,IAAI,EACR,OAAO;IAGX,OAAO,WAAP,GAAO,sCAACf,gBAAcA;QAAE,GAAGc,KAAK;QAAG,GAAGC,GAAG,IAAI;QAAE,eAAeZ;;AAClE;AACA,MAAMc,kBAAkBC,gBAAgB,mBAAmBL"}
package/Tabs/Tabs.d.ts CHANGED
@@ -1,15 +1,20 @@
1
1
  import React from "react";
2
2
  import { Tabs as TabsPrimitive } from "radix-ui";
3
3
  import { type VariantProps } from "../utils.js";
4
- import type { TabProps, tabListVariants } from "./components/index.js";
4
+ import type { TabProps } from "./components/index.js";
5
+ import { tabListVariants } from "./components/index.js";
5
6
  interface TabsProps extends Omit<TabsPrimitive.TabsProps, "children"> {
6
7
  tabs: React.ReactElement<TabProps>[];
7
8
  size?: VariantProps<typeof tabListVariants>["size"];
8
9
  spacing?: VariantProps<typeof tabListVariants>["spacing"];
9
10
  separator?: VariantProps<typeof tabListVariants>["separator"];
10
11
  loading?: boolean;
12
+ /**
13
+ * Controls rendered at the end of the tab row, e.g. a filter checkbox or a button.
14
+ */
15
+ actions?: React.ReactNode;
11
16
  }
12
- declare const DecoratableTabs: ({ defaultValue: initialValue, size, spacing, separator, loading, tabs: tabComponents, ...props }: TabsProps) => React.JSX.Element;
17
+ declare const DecoratableTabs: ({ defaultValue: initialValue, size, spacing, separator, loading, actions, tabs: tabComponents, ...props }: TabsProps) => React.JSX.Element;
13
18
  declare const Tabs: typeof DecoratableTabs & {
14
19
  original: typeof DecoratableTabs;
15
20
  originalName: string;
package/Tabs/Tabs.js CHANGED
@@ -1,20 +1,16 @@
1
1
  import react, { useMemo, useState } from "react";
2
2
  import { Tabs } from "radix-ui";
3
- import { makeDecoratable, withStaticProps } from "../utils.js";
4
- import { Content, List, Tab, TabsContext, Trigger } from "./components/index.js";
3
+ import { cn, makeDecoratable, withStaticProps } from "../utils.js";
4
+ import { Content, List, Tab, TabsContext, Trigger, tabListVariants } from "./components/index.js";
5
5
  const Root = Tabs.Root;
6
- const DecoratableTabs = ({ defaultValue: initialValue, size, spacing, separator, loading, tabs: tabComponents, ...props })=>{
6
+ const DecoratableTabs = ({ defaultValue: initialValue, size, spacing, separator, loading, actions, tabs: tabComponents, ...props })=>{
7
7
  const [tabs, setTabs] = useState([]);
8
8
  const defaultValue = useMemo(()=>initialValue || tabComponents.find((tab)=>!tab.props.disabled && false !== tab.props.visible)?.props.value, [
9
9
  initialValue,
10
10
  tabComponents
11
11
  ]);
12
- const triggers = useMemo(()=>/*#__PURE__*/ react.createElement(List, {
13
- key: tabs.map((tab)=>tab.id).join(";"),
14
- size: size,
15
- spacing: spacing,
16
- separator: separator
17
- }, tabs.map((tab)=>/*#__PURE__*/ react.createElement(Trigger, {
12
+ const triggers = useMemo(()=>{
13
+ const triggerList = tabs.map((tab)=>/*#__PURE__*/ react.createElement(Trigger, {
18
14
  "data-testid": tab["data-testid"],
19
15
  disabled: tab.disabled,
20
16
  icon: tab.icon,
@@ -24,12 +20,34 @@ const DecoratableTabs = ({ defaultValue: initialValue, size, spacing, separator,
24
20
  text: tab.trigger,
25
21
  value: tab.value,
26
22
  visible: tab.visible
27
- }))), [
23
+ }));
24
+ const listKey = tabs.map((tab)=>tab.id).join(";");
25
+ if (!actions) return /*#__PURE__*/ react.createElement(List, {
26
+ key: listKey,
27
+ size: size,
28
+ spacing: spacing,
29
+ separator: separator
30
+ }, triggerList);
31
+ return /*#__PURE__*/ react.createElement("div", {
32
+ className: cn(tabListVariants({
33
+ size,
34
+ spacing,
35
+ separator
36
+ }))
37
+ }, /*#__PURE__*/ react.createElement(List, {
38
+ key: listKey,
39
+ size: size,
40
+ className: "w-auto"
41
+ }, triggerList), /*#__PURE__*/ react.createElement("div", {
42
+ className: "ml-auto flex items-center gap-sm"
43
+ }, actions));
44
+ }, [
28
45
  tabs,
29
46
  size,
30
47
  spacing,
31
48
  separator,
32
- loading
49
+ loading,
50
+ actions
33
51
  ]);
34
52
  const contents = useMemo(()=>tabs.map((tab)=>/*#__PURE__*/ react.createElement(Content, {
35
53
  key: tab.id,
package/Tabs/Tabs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs/Tabs.js","sources":["../../src/Tabs/Tabs.tsx"],"sourcesContent":["import React, { useMemo, useState } from \"react\";\nimport { Tabs as TabsPrimitive } from \"radix-ui\";\nimport { makeDecoratable, type VariantProps, withStaticProps } from \"~/utils.js\";\nimport type { ITabsContext, TabItem, TabProps, tabListVariants } from \"./components/index.js\";\nimport { Content, List, Tab, TabsContext, Trigger } from \"./components/index.js\";\n\nconst Root = TabsPrimitive.Root;\n\ninterface TabsProps extends Omit<TabsPrimitive.TabsProps, \"children\"> {\n tabs: React.ReactElement<TabProps>[];\n size?: VariantProps<typeof tabListVariants>[\"size\"];\n spacing?: VariantProps<typeof tabListVariants>[\"spacing\"];\n separator?: VariantProps<typeof tabListVariants>[\"separator\"];\n loading?: boolean;\n}\n\nconst DecoratableTabs = ({\n defaultValue: initialValue,\n size,\n spacing,\n separator,\n loading,\n tabs: tabComponents,\n ...props\n}: TabsProps) => {\n const [tabs, setTabs] = useState<TabItem[]>([]);\n\n const defaultValue = useMemo(() => {\n return (\n initialValue ||\n tabComponents.find(tab => !tab.props.disabled && tab.props.visible !== false)?.props\n .value\n );\n }, [initialValue, tabComponents]);\n\n const triggers = useMemo(\n () => (\n <List\n key={tabs.map(tab => tab.id).join(\";\")}\n size={size}\n spacing={spacing}\n separator={separator}\n >\n {tabs.map(tab => (\n <Trigger\n data-testid={tab[\"data-testid\"]}\n disabled={tab.disabled}\n icon={tab.icon}\n key={tab.id}\n loading={loading}\n size={size}\n text={tab.trigger}\n value={tab.value}\n visible={tab.visible}\n />\n ))}\n </List>\n ),\n [tabs, size, spacing, separator, loading]\n );\n\n const contents = useMemo(\n () =>\n tabs.map(tab => (\n <Content\n key={tab.id}\n value={tab.value}\n content={tab.content}\n spacing={tab.spacing ?? spacing}\n className={tab.className}\n />\n )),\n [tabs, spacing]\n );\n\n const context: ITabsContext = useMemo(\n () => ({\n addTab(props) {\n setTabs(tabs => {\n const existingIndex = tabs.findIndex(tab => tab.value === props.value);\n if (existingIndex > -1) {\n return [\n ...tabs.slice(0, existingIndex),\n props,\n ...tabs.slice(existingIndex + 1)\n ];\n }\n return [...tabs, props];\n });\n },\n removeTab(id) {\n setTabs(tabs => tabs.filter(tab => tab.id !== id));\n }\n }),\n [setTabs]\n );\n\n return (\n <Root {...props} defaultValue={defaultValue}>\n {triggers}\n {contents}\n <TabsContext.Provider value={context}>{tabComponents}</TabsContext.Provider>\n </Root>\n );\n};\n\nconst BaseTabs = makeDecoratable(\"Tabs\", DecoratableTabs);\n\nconst Tabs = withStaticProps(BaseTabs, {\n Tab\n});\n\nexport { Tabs, type TabsProps };\n"],"names":["Root","TabsPrimitive","DecoratableTabs","initialValue","size","spacing","separator","loading","tabComponents","props","tabs","setTabs","useState","defaultValue","useMemo","tab","triggers","List","Trigger","contents","Content","context","existingIndex","id","TabsContext","BaseTabs","makeDecoratable","Tabs","withStaticProps","Tab"],"mappings":";;;;AAMA,MAAMA,OAAOC,KAAAA,IAAkB;AAU/B,MAAMC,kBAAkB,CAAC,EACrB,cAAcC,YAAY,EAC1BC,IAAI,EACJC,OAAO,EACPC,SAAS,EACTC,OAAO,EACP,MAAMC,aAAa,EACnB,GAAGC,OACK;IACR,MAAM,CAACC,MAAMC,QAAQ,GAAGC,SAAoB,EAAE;IAE9C,MAAMC,eAAeC,QAAQ,IAErBX,gBACAK,cAAc,IAAI,CAACO,CAAAA,MAAO,CAACA,IAAI,KAAK,CAAC,QAAQ,IAAIA,AAAsB,UAAtBA,IAAI,KAAK,CAAC,OAAO,GAAa,MAC1E,OAEV;QAACZ;QAAcK;KAAc;IAEhC,MAAMQ,WAAWF,QACb,kBACI,oBAACG,MAAIA;YACD,KAAKP,KAAK,GAAG,CAACK,CAAAA,MAAOA,IAAI,EAAE,EAAE,IAAI,CAAC;YAClC,MAAMX;YACN,SAASC;YACT,WAAWC;WAEVI,KAAK,GAAG,CAACK,CAAAA,MAAAA,WAAAA,GACN,oBAACG,SAAOA;gBACJ,eAAaH,GAAG,CAAC,cAAc;gBAC/B,UAAUA,IAAI,QAAQ;gBACtB,MAAMA,IAAI,IAAI;gBACd,KAAKA,IAAI,EAAE;gBACX,SAASR;gBACT,MAAMH;gBACN,MAAMW,IAAI,OAAO;gBACjB,OAAOA,IAAI,KAAK;gBAChB,SAASA,IAAI,OAAO;kBAKpC;QAACL;QAAMN;QAAMC;QAASC;QAAWC;KAAQ;IAG7C,MAAMY,WAAWL,QACb,IACIJ,KAAK,GAAG,CAACK,CAAAA,MAAAA,WAAAA,GACL,oBAACK,SAAOA;gBACJ,KAAKL,IAAI,EAAE;gBACX,OAAOA,IAAI,KAAK;gBAChB,SAASA,IAAI,OAAO;gBACpB,SAASA,IAAI,OAAO,IAAIV;gBACxB,WAAWU,IAAI,SAAS;iBAGpC;QAACL;QAAML;KAAQ;IAGnB,MAAMgB,UAAwBP,QAC1B,IAAO;YACH,QAAOL,KAAK;gBACRE,QAAQD,CAAAA;oBACJ,MAAMY,gBAAgBZ,KAAK,SAAS,CAACK,CAAAA,MAAOA,IAAI,KAAK,KAAKN,MAAM,KAAK;oBACrE,IAAIa,gBAAgB,IAChB,OAAO;2BACAZ,KAAK,KAAK,CAAC,GAAGY;wBACjBb;2BACGC,KAAK,KAAK,CAACY,gBAAgB;qBACjC;oBAEL,OAAO;2BAAIZ;wBAAMD;qBAAM;gBAC3B;YACJ;YACA,WAAUc,EAAE;gBACRZ,QAAQD,CAAAA,OAAQA,KAAK,MAAM,CAACK,CAAAA,MAAOA,IAAI,EAAE,KAAKQ;YAClD;QACJ,IACA;QAACZ;KAAQ;IAGb,OAAO,WAAP,GACI,oBAACX,MAAIA;QAAE,GAAGS,KAAK;QAAE,cAAcI;OAC1BG,UACAG,UAAAA,WAAAA,GACD,oBAACK,YAAY,QAAQ;QAAC,OAAOH;OAAUb;AAGnD;AAEA,MAAMiB,WAAWC,gBAAgB,QAAQxB;AAEzC,MAAMyB,YAAOC,gBAAgBH,UAAU;IACnCI,KAAGA;AACP"}
1
+ {"version":3,"file":"Tabs/Tabs.js","sources":["../../src/Tabs/Tabs.tsx"],"sourcesContent":["import React, { useMemo, useState } from \"react\";\nimport { Tabs as TabsPrimitive } from \"radix-ui\";\nimport { cn, makeDecoratable, type VariantProps, withStaticProps } from \"~/utils.js\";\nimport type { ITabsContext, TabItem, TabProps } from \"./components/index.js\";\nimport { Content, List, Tab, TabsContext, Trigger, tabListVariants } from \"./components/index.js\";\n\nconst Root = TabsPrimitive.Root;\n\ninterface TabsProps extends Omit<TabsPrimitive.TabsProps, \"children\"> {\n tabs: React.ReactElement<TabProps>[];\n size?: VariantProps<typeof tabListVariants>[\"size\"];\n spacing?: VariantProps<typeof tabListVariants>[\"spacing\"];\n separator?: VariantProps<typeof tabListVariants>[\"separator\"];\n loading?: boolean;\n /**\n * Controls rendered at the end of the tab row, e.g. a filter checkbox or a button.\n */\n actions?: React.ReactNode;\n}\n\nconst DecoratableTabs = ({\n defaultValue: initialValue,\n size,\n spacing,\n separator,\n loading,\n actions,\n tabs: tabComponents,\n ...props\n}: TabsProps) => {\n const [tabs, setTabs] = useState<TabItem[]>([]);\n\n const defaultValue = useMemo(() => {\n return (\n initialValue ||\n tabComponents.find(tab => !tab.props.disabled && tab.props.visible !== false)?.props\n .value\n );\n }, [initialValue, tabComponents]);\n\n const triggers = useMemo(() => {\n const triggerList = tabs.map(tab => (\n <Trigger\n data-testid={tab[\"data-testid\"]}\n disabled={tab.disabled}\n icon={tab.icon}\n key={tab.id}\n loading={loading}\n size={size}\n text={tab.trigger}\n value={tab.value}\n visible={tab.visible}\n />\n ));\n const listKey = tabs.map(tab => tab.id).join(\";\");\n\n if (!actions) {\n return (\n <List key={listKey} size={size} spacing={spacing} separator={separator}>\n {triggerList}\n </List>\n );\n }\n\n // Actions sit outside the tablist, so arrow keys only move between tabs.\n return (\n <div className={cn(tabListVariants({ size, spacing, separator }))}>\n <List key={listKey} size={size} className={\"w-auto\"}>\n {triggerList}\n </List>\n <div className={\"ml-auto flex items-center gap-sm\"}>{actions}</div>\n </div>\n );\n }, [tabs, size, spacing, separator, loading, actions]);\n\n const contents = useMemo(\n () =>\n tabs.map(tab => (\n <Content\n key={tab.id}\n value={tab.value}\n content={tab.content}\n spacing={tab.spacing ?? spacing}\n className={tab.className}\n />\n )),\n [tabs, spacing]\n );\n\n const context: ITabsContext = useMemo(\n () => ({\n addTab(props) {\n setTabs(tabs => {\n const existingIndex = tabs.findIndex(tab => tab.value === props.value);\n if (existingIndex > -1) {\n return [\n ...tabs.slice(0, existingIndex),\n props,\n ...tabs.slice(existingIndex + 1)\n ];\n }\n return [...tabs, props];\n });\n },\n removeTab(id) {\n setTabs(tabs => tabs.filter(tab => tab.id !== id));\n }\n }),\n [setTabs]\n );\n\n return (\n <Root {...props} defaultValue={defaultValue}>\n {triggers}\n {contents}\n <TabsContext.Provider value={context}>{tabComponents}</TabsContext.Provider>\n </Root>\n );\n};\n\nconst BaseTabs = makeDecoratable(\"Tabs\", DecoratableTabs);\n\nconst Tabs = withStaticProps(BaseTabs, {\n Tab\n});\n\nexport { Tabs, type TabsProps };\n"],"names":["Root","TabsPrimitive","DecoratableTabs","initialValue","size","spacing","separator","loading","actions","tabComponents","props","tabs","setTabs","useState","defaultValue","useMemo","tab","triggers","triggerList","Trigger","listKey","List","cn","tabListVariants","contents","Content","context","existingIndex","id","TabsContext","BaseTabs","makeDecoratable","Tabs","withStaticProps","Tab"],"mappings":";;;;AAMA,MAAMA,OAAOC,KAAAA,IAAkB;AAc/B,MAAMC,kBAAkB,CAAC,EACrB,cAAcC,YAAY,EAC1BC,IAAI,EACJC,OAAO,EACPC,SAAS,EACTC,OAAO,EACPC,OAAO,EACP,MAAMC,aAAa,EACnB,GAAGC,OACK;IACR,MAAM,CAACC,MAAMC,QAAQ,GAAGC,SAAoB,EAAE;IAE9C,MAAMC,eAAeC,QAAQ,IAErBZ,gBACAM,cAAc,IAAI,CAACO,CAAAA,MAAO,CAACA,IAAI,KAAK,CAAC,QAAQ,IAAIA,AAAsB,UAAtBA,IAAI,KAAK,CAAC,OAAO,GAAa,MAC1E,OAEV;QAACb;QAAcM;KAAc;IAEhC,MAAMQ,WAAWF,QAAQ;QACrB,MAAMG,cAAcP,KAAK,GAAG,CAACK,CAAAA,MAAAA,WAAAA,GACzB,oBAACG,SAAOA;gBACJ,eAAaH,GAAG,CAAC,cAAc;gBAC/B,UAAUA,IAAI,QAAQ;gBACtB,MAAMA,IAAI,IAAI;gBACd,KAAKA,IAAI,EAAE;gBACX,SAAST;gBACT,MAAMH;gBACN,MAAMY,IAAI,OAAO;gBACjB,OAAOA,IAAI,KAAK;gBAChB,SAASA,IAAI,OAAO;;QAG5B,MAAMI,UAAUT,KAAK,GAAG,CAACK,CAAAA,MAAOA,IAAI,EAAE,EAAE,IAAI,CAAC;QAE7C,IAAI,CAACR,SACD,OAAO,WAAP,GACI,oBAACa,MAAIA;YAAC,KAAKD;YAAS,MAAMhB;YAAM,SAASC;YAAS,WAAWC;WACxDY;QAMb,OAAO,WAAP,GACI,oBAAC;YAAI,WAAWI,GAAGC,gBAAgB;gBAAEnB;gBAAMC;gBAASC;YAAU;yBAC1D,oBAACe,MAAIA;YAAC,KAAKD;YAAS,MAAMhB;YAAM,WAAW;WACtCc,cAAAA,WAAAA,GAEL,oBAAC;YAAI,WAAW;WAAqCV;IAGjE,GAAG;QAACG;QAAMP;QAAMC;QAASC;QAAWC;QAASC;KAAQ;IAErD,MAAMgB,WAAWT,QACb,IACIJ,KAAK,GAAG,CAACK,CAAAA,MAAAA,WAAAA,GACL,oBAACS,SAAOA;gBACJ,KAAKT,IAAI,EAAE;gBACX,OAAOA,IAAI,KAAK;gBAChB,SAASA,IAAI,OAAO;gBACpB,SAASA,IAAI,OAAO,IAAIX;gBACxB,WAAWW,IAAI,SAAS;iBAGpC;QAACL;QAAMN;KAAQ;IAGnB,MAAMqB,UAAwBX,QAC1B,IAAO;YACH,QAAOL,KAAK;gBACRE,QAAQD,CAAAA;oBACJ,MAAMgB,gBAAgBhB,KAAK,SAAS,CAACK,CAAAA,MAAOA,IAAI,KAAK,KAAKN,MAAM,KAAK;oBACrE,IAAIiB,gBAAgB,IAChB,OAAO;2BACAhB,KAAK,KAAK,CAAC,GAAGgB;wBACjBjB;2BACGC,KAAK,KAAK,CAACgB,gBAAgB;qBACjC;oBAEL,OAAO;2BAAIhB;wBAAMD;qBAAM;gBAC3B;YACJ;YACA,WAAUkB,EAAE;gBACRhB,QAAQD,CAAAA,OAAQA,KAAK,MAAM,CAACK,CAAAA,MAAOA,IAAI,EAAE,KAAKY;YAClD;QACJ,IACA;QAAChB;KAAQ;IAGb,OAAO,WAAP,GACI,oBAACZ,MAAIA;QAAE,GAAGU,KAAK;QAAE,cAAcI;OAC1BG,UACAO,UAAAA,WAAAA,GACD,oBAACK,YAAY,QAAQ;QAAC,OAAOH;OAAUjB;AAGnD;AAEA,MAAMqB,WAAWC,gBAAgB,QAAQ7B;AAEzC,MAAM8B,YAAOC,gBAAgBH,UAAU;IACnCI,KAAGA;AACP"}