@tcn/ui 0.16.0 → 0.18.0
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.
- package/dist/actions/index.d.ts +0 -1
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +6 -8
- package/dist/actions/index.js.map +1 -1
- package/dist/card.css +1 -0
- package/dist/column.css +1 -1
- package/dist/containers.css +1 -1
- package/dist/containers.module-BmICKsOK.js +5 -0
- package/dist/containers.module-BmICKsOK.js.map +1 -0
- package/dist/draggable.css +1 -1
- package/dist/draggable.module-DFYR5n3n.js +5 -0
- package/dist/draggable.module-DFYR5n3n.js.map +1 -0
- package/dist/field_set.css +1 -1
- package/dist/field_set.module-BpJTFCi4.js +5 -0
- package/dist/field_set.module-BpJTFCi4.js.map +1 -0
- package/dist/form/field/field.js +17 -13
- package/dist/form/field/field.js.map +1 -1
- package/dist/form/field_set/field_set.d.ts +6 -10
- package/dist/form/field_set/field_set.d.ts.map +1 -1
- package/dist/form/field_set/field_set.js +33 -61
- package/dist/form/field_set/field_set.js.map +1 -1
- package/dist/form/field_set/legend.d.ts +20 -0
- package/dist/form/field_set/legend.d.ts.map +1 -0
- package/dist/form/field_set/legend.js +28 -0
- package/dist/form/field_set/legend.js.map +1 -0
- package/dist/form/index.d.ts +2 -1
- package/dist/form/index.d.ts.map +1 -1
- package/dist/form/index.js +24 -22
- package/dist/form/index.js.map +1 -1
- package/dist/inputs/color_input/color_input.js +2 -3
- package/dist/inputs/color_input/color_input.js.map +1 -1
- package/dist/inputs/color_input/color_picker.js +11 -7
- package/dist/inputs/color_input/color_picker.js.map +1 -1
- package/dist/inputs/combo_box/combo_box.js +24 -20
- package/dist/inputs/combo_box/combo_box.js.map +1 -1
- package/dist/inputs/date_picker/date_picker.js +19 -15
- package/dist/inputs/date_picker/date_picker.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_header.d.ts.map +1 -1
- package/dist/inputs/date_picker/date_picker_header.js +15 -14
- package/dist/inputs/date_picker/date_picker_header.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_input.js +26 -23
- package/dist/inputs/date_picker/date_picker_input.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_time_selector.js +2 -3
- package/dist/inputs/date_picker/date_picker_time_selector.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_year_input.js +2 -3
- package/dist/inputs/date_picker/date_picker_year_input.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_year_selector.js +24 -21
- package/dist/inputs/date_picker/date_picker_year_selector.js.map +1 -1
- package/dist/inputs/mask_input/key_capture_input.js +35 -31
- package/dist/inputs/mask_input/key_capture_input.js.map +1 -1
- package/dist/inputs/mask_input/mask_input.js +18 -14
- package/dist/inputs/mask_input/mask_input.js.map +1 -1
- package/dist/inputs/multiselect/multiselect.js +28 -24
- package/dist/inputs/multiselect/multiselect.js.map +1 -1
- package/dist/inputs/multiselect/multiselect_inline_values.d.ts.map +1 -1
- package/dist/inputs/multiselect/multiselect_inline_values.js +15 -15
- package/dist/inputs/multiselect/multiselect_inline_values.js.map +1 -1
- package/dist/inputs/multiselect/multiselect_values.js +16 -17
- package/dist/inputs/multiselect/multiselect_values.js.map +1 -1
- package/dist/inputs/phone_number_input/phone_number_context.js +13 -9
- package/dist/inputs/phone_number_input/phone_number_context.js.map +1 -1
- package/dist/inputs/phone_number_input/phone_number_input_adapter.js +2 -3
- package/dist/inputs/phone_number_input/phone_number_input_adapter.js.map +1 -1
- package/dist/inputs/phone_number_input/sip_input.js +8 -9
- package/dist/inputs/phone_number_input/sip_input.js.map +1 -1
- package/dist/inputs/select/select.js +11 -8
- package/dist/inputs/select/select.js.map +1 -1
- package/dist/inputs/slider/slider.js +28 -24
- package/dist/inputs/slider/slider.js.map +1 -1
- package/dist/inputs/suggestions/suggestion_list.js +11 -8
- package/dist/inputs/suggestions/suggestion_list.js.map +1 -1
- package/dist/inputs/switch/switch.js +29 -25
- package/dist/inputs/switch/switch.js.map +1 -1
- package/dist/inputs/unit_input/unit_input.js +21 -17
- package/dist/inputs/unit_input/unit_input.js.map +1 -1
- package/dist/layouts/containers/columns/columns.d.ts +6 -1
- package/dist/layouts/containers/columns/columns.d.ts.map +1 -1
- package/dist/layouts/containers/columns/columns.js +30 -7
- package/dist/layouts/containers/columns/columns.js.map +1 -1
- package/dist/layouts/containers/rail.d.ts +2 -5
- package/dist/layouts/containers/rail.d.ts.map +1 -1
- package/dist/layouts/containers/rail.js +17 -55
- package/dist/layouts/containers/rail.js.map +1 -1
- package/dist/layouts/containers/rows/index.d.ts +3 -0
- package/dist/layouts/containers/rows/index.d.ts.map +1 -0
- package/dist/layouts/containers/rows/index.js +7 -0
- package/dist/layouts/containers/rows/index.js.map +1 -0
- package/dist/layouts/containers/rows/row.d.ts +6 -0
- package/dist/layouts/containers/rows/row.d.ts.map +1 -0
- package/dist/layouts/containers/rows/row.js +20 -0
- package/dist/layouts/containers/rows/row.js.map +1 -0
- package/dist/layouts/containers/rows/rows.d.ts +11 -0
- package/dist/layouts/containers/rows/rows.d.ts.map +1 -0
- package/dist/layouts/containers/rows/rows.js +34 -0
- package/dist/layouts/containers/rows/rows.js.map +1 -0
- package/dist/layouts/containers/scaffold.d.ts +2 -5
- package/dist/layouts/containers/scaffold.d.ts.map +1 -1
- package/dist/layouts/containers/scaffold.js +17 -55
- package/dist/layouts/containers/scaffold.js.map +1 -1
- package/dist/layouts/index.d.ts +2 -0
- package/dist/layouts/index.d.ts.map +1 -1
- package/dist/layouts/index.js +26 -22
- package/dist/layouts/index.js.map +1 -1
- package/dist/mobile/inputs/date_picker/mobile_date_picker_header.js +11 -7
- package/dist/mobile/inputs/date_picker/mobile_date_picker_header.js.map +1 -1
- package/dist/mobile/inputs/date_picker/mobile_date_picker_input.js +11 -7
- package/dist/mobile/inputs/date_picker/mobile_date_picker_input.js.map +1 -1
- package/dist/mobile/inputs/date_picker/mobile_date_picker_year_selector.js +14 -10
- package/dist/mobile/inputs/date_picker/mobile_date_picker_year_selector.js.map +1 -1
- package/dist/multiselect_values.css +1 -1
- package/dist/navigation/tabs/state/link/tab_link.js +15 -11
- package/dist/navigation/tabs/state/link/tab_link.js.map +1 -1
- package/dist/overlay/frame/frame.d.ts.map +1 -1
- package/dist/overlay/frame/frame.js +117 -76
- package/dist/overlay/frame/frame.js.map +1 -1
- package/dist/overlay/menu/menu.js +21 -17
- package/dist/overlay/menu/menu.js.map +1 -1
- package/dist/overlay/popper/base/dismissal_decorator.js +3 -3
- package/dist/overlay/popper/base/dismissal_decorator.js.map +1 -1
- package/dist/overlay/popper/context_popper.js +14 -10
- package/dist/overlay/popper/context_popper.js.map +1 -1
- package/dist/overlay/popper/element_popper.js +15 -11
- package/dist/overlay/popper/element_popper.js.map +1 -1
- package/dist/overlay/popper/legacy/popper.js +32 -28
- package/dist/overlay/popper/legacy/popper.js.map +1 -1
- package/dist/overlay/popper/preview_popper.js +16 -12
- package/dist/overlay/popper/preview_popper.js.map +1 -1
- package/dist/overlay/tethered/tethered.js +17 -13
- package/dist/overlay/tethered/tethered.js.map +1 -1
- package/dist/resizable.css +1 -0
- package/dist/resizable.module-ur5FBfxo.js +5 -0
- package/dist/resizable.module-ur5FBfxo.js.map +1 -0
- package/dist/resize_handle.css +1 -0
- package/dist/row.css +1 -0
- package/dist/stacks/box/box.d.ts +14 -0
- package/dist/stacks/box/box.d.ts.map +1 -1
- package/dist/stacks/box/box.js +104 -102
- package/dist/stacks/box/box.js.map +1 -1
- package/dist/stacks/box/detect_resize_bounds.d.ts +1 -0
- package/dist/stacks/box/detect_resize_bounds.d.ts.map +1 -1
- package/dist/stacks/box/detect_resize_bounds.js +22 -20
- package/dist/stacks/box/detect_resize_bounds.js.map +1 -1
- package/dist/stacks/box/end_resize_handle.js +5 -5
- package/dist/stacks/box/end_resize_handle.js.map +1 -1
- package/dist/stacks/box/resize_handlers.d.ts.map +1 -1
- package/dist/stacks/box/resize_handlers.js +12 -12
- package/dist/stacks/box/resize_handlers.js.map +1 -1
- package/dist/stacks/box/start_resize_handle.js +7 -7
- package/dist/stacks/box/start_resize_handle.js.map +1 -1
- package/dist/stacks/box/types.d.ts +3 -2
- package/dist/stacks/box/types.d.ts.map +1 -1
- package/dist/stacks/h_collapsible_box.js +24 -20
- package/dist/stacks/h_collapsible_box.js.map +1 -1
- package/dist/stacks/v_collapsible_box.js +26 -22
- package/dist/stacks/v_collapsible_box.js.map +1 -1
- package/dist/surfaces/alert/alert.js +7 -8
- package/dist/surfaces/alert/alert.js.map +1 -1
- package/dist/surfaces/card/card.d.ts.map +1 -1
- package/dist/surfaces/card/card.js +14 -6
- package/dist/surfaces/card/card.js.map +1 -1
- package/dist/surfaces/pop_confirm/pop_confirm.js +4 -2
- package/dist/surfaces/pop_confirm/pop_confirm.js.map +1 -1
- package/dist/test-setup.d.ts +2 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +10 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/themes/stories/button_showcase.d.ts.map +1 -1
- package/dist/themes/stories/controls_fieldset.d.ts.map +1 -1
- package/dist/themes/stories/menu_showcase.d.ts.map +1 -1
- package/dist/themes/theme.d.ts.map +1 -1
- package/dist/themes/theme.js +17 -22
- package/dist/themes/theme.js.map +1 -1
- package/dist/themes/themes/ergo/ergo_theme.css +1 -1
- package/dist/themes/themes/ergo/ergo_theme.d.ts.map +1 -1
- package/dist/themes/themes/ergo/ergo_theme.js +653 -431
- package/dist/themes/themes/ergo/ergo_theme.js.map +1 -1
- package/dist/themes/themes/ergo/parts/actions.css +1 -0
- package/dist/themes/themes/ergo/parts/base.css +1 -0
- package/dist/themes/themes/ergo/parts/form.css +1 -0
- package/dist/themes/themes/ergo/parts/inputs.css +1 -0
- package/dist/themes/themes/ergo/parts/navigation.css +1 -0
- package/dist/themes/themes/windows_98/windows_98.css +1 -1
- package/dist/themes/themes/windows_98/windows_98_theme.js +32 -43
- package/dist/themes/themes/windows_98/windows_98_theme.js.map +1 -1
- package/dist/utils/decorators/clone_with_decorator.d.ts +21 -0
- package/dist/utils/decorators/clone_with_decorator.d.ts.map +1 -0
- package/dist/utils/decorators/clone_with_decorator.js +16 -0
- package/dist/utils/decorators/clone_with_decorator.js.map +1 -0
- package/dist/utils/decorators/draggable/context.d.ts.map +1 -0
- package/dist/utils/decorators/draggable/context.js.map +1 -0
- package/dist/utils/{dnd/handle.d.ts → decorators/draggable/drag_handle.d.ts} +1 -1
- package/dist/utils/decorators/draggable/drag_handle.d.ts.map +1 -0
- package/dist/utils/{dnd/handle.js → decorators/draggable/drag_handle.js} +2 -2
- package/dist/utils/decorators/draggable/drag_handle.js.map +1 -0
- package/dist/utils/decorators/draggable/draggable.d.ts.map +1 -0
- package/dist/utils/{dnd → decorators}/draggable/draggable.js +3 -3
- package/dist/utils/decorators/draggable/draggable.js.map +1 -0
- package/dist/utils/decorators/draggable/index.d.ts +11 -0
- package/dist/utils/decorators/draggable/index.d.ts.map +1 -0
- package/dist/utils/decorators/draggable/index.js +14 -0
- package/dist/utils/decorators/draggable/index.js.map +1 -0
- package/dist/utils/{dnd → decorators/draggable}/types.d.ts +1 -1
- package/dist/utils/decorators/draggable/types.d.ts.map +1 -0
- package/dist/utils/{dnd/hooks → decorators/draggable}/use_drag_container.d.ts +2 -2
- package/dist/utils/decorators/draggable/use_drag_container.d.ts.map +1 -0
- package/dist/utils/decorators/draggable/use_drag_container.js.map +1 -0
- package/dist/utils/decorators/draggable/use_draggable.d.ts.map +1 -0
- package/dist/utils/decorators/draggable/use_draggable.js.map +1 -0
- package/dist/utils/decorators/index.d.ts +3 -0
- package/dist/utils/decorators/index.d.ts.map +1 -0
- package/dist/utils/decorators/index.js +27 -0
- package/dist/utils/decorators/index.js.map +1 -0
- package/dist/utils/decorators/resizable/context.d.ts +4 -0
- package/dist/utils/decorators/resizable/context.d.ts.map +1 -0
- package/dist/utils/decorators/resizable/context.js +10 -0
- package/dist/utils/decorators/resizable/context.js.map +1 -0
- package/dist/utils/decorators/resizable/handle_config.d.ts +32 -0
- package/dist/utils/decorators/resizable/handle_config.d.ts.map +1 -0
- package/dist/utils/decorators/resizable/handle_config.js +62 -0
- package/dist/utils/decorators/resizable/handle_config.js.map +1 -0
- package/dist/utils/decorators/resizable/index.d.ts +10 -0
- package/dist/utils/decorators/resizable/index.d.ts.map +1 -0
- package/dist/utils/decorators/resizable/index.js +16 -0
- package/dist/utils/decorators/resizable/index.js.map +1 -0
- package/dist/utils/decorators/resizable/resizable.d.ts +11 -0
- package/dist/utils/decorators/resizable/resizable.d.ts.map +1 -0
- package/dist/utils/decorators/resizable/resizable.js +52 -0
- package/dist/utils/decorators/resizable/resizable.js.map +1 -0
- package/dist/utils/decorators/resizable/resize_handle.d.ts +7 -0
- package/dist/utils/decorators/resizable/resize_handle.d.ts.map +1 -0
- package/dist/utils/decorators/resizable/resize_handle.js +100 -0
- package/dist/utils/decorators/resizable/resize_handle.js.map +1 -0
- package/dist/utils/decorators/resizable/resize_strategy.d.ts +47 -0
- package/dist/utils/decorators/resizable/resize_strategy.d.ts.map +1 -0
- package/dist/utils/decorators/resizable/resize_strategy.js +108 -0
- package/dist/utils/decorators/resizable/resize_strategy.js.map +1 -0
- package/dist/utils/decorators/resizable/types.d.ts +28 -0
- package/dist/utils/decorators/resizable/types.d.ts.map +1 -0
- package/dist/utils/decorators/resizable/types.js +2 -0
- package/dist/utils/decorators/resizable/types.js.map +1 -0
- package/dist/utils/hooks/labelled_by_context.d.ts +21 -0
- package/dist/utils/hooks/labelled_by_context.d.ts.map +1 -0
- package/dist/utils/hooks/labelled_by_context.js +12 -0
- package/dist/utils/hooks/labelled_by_context.js.map +1 -0
- package/dist/utils/index.d.ts +8 -7
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +45 -28
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/listeners/click_away_listener.d.ts.map +1 -0
- package/dist/utils/{click_away_listener.js → listeners/click_away_listener.js} +1 -1
- package/dist/utils/listeners/click_away_listener.js.map +1 -0
- package/dist/utils/listeners/focus_redirect.d.ts.map +1 -0
- package/dist/utils/listeners/focus_redirect.js.map +1 -0
- package/dist/utils/listeners/index.d.ts +4 -0
- package/dist/utils/listeners/index.d.ts.map +1 -0
- package/dist/utils/listeners/index.js +10 -0
- package/dist/utils/listeners/index.js.map +1 -0
- package/dist/utils/listeners/mouse_leave_region.d.ts.map +1 -0
- package/dist/utils/listeners/mouse_leave_region.js.map +1 -0
- package/dist/utils/listeners/scroll_away_listener.d.ts.map +1 -0
- package/dist/utils/{scroll_away_listener.js → listeners/scroll_away_listener.js} +1 -1
- package/dist/utils/listeners/scroll_away_listener.js.map +1 -0
- package/dist/utils/system/index.d.ts +2 -0
- package/dist/utils/system/index.d.ts.map +1 -0
- package/dist/utils/system/index.js +2 -0
- package/dist/utils/system/index.js.map +1 -0
- package/dist/utils/system/variations.d.ts.map +1 -0
- package/dist/utils/system/variations.js +2 -0
- package/dist/utils/system/variations.js.map +1 -0
- package/dist/utils/types/sides.d.ts +3 -0
- package/dist/utils/types/sides.d.ts.map +1 -0
- package/package.json +3 -9
- package/src/actions/button/__stories__/button_group.stories.tsx +23 -24
- package/src/actions/index.ts +0 -1
- package/src/form/field/field.stories.tsx +2 -2
- package/src/form/field/h_field/h_field.stories.tsx +1 -1
- package/src/form/field/v_field/v_field.stories.tsx +1 -1
- package/src/form/field_set/field_set.module.css +0 -14
- package/src/form/field_set/field_set.stories.tsx +101 -1
- package/src/form/field_set/field_set.tsx +43 -57
- package/src/form/field_set/legend.tsx +44 -0
- package/src/form/index.ts +6 -1
- package/src/inputs/date_picker/date_picker_header.tsx +7 -5
- package/src/inputs/date_picker/date_picker_year_selector.tsx +5 -5
- package/src/inputs/multiselect/multiselect_inline_values.tsx +4 -3
- package/src/inputs/multiselect/multiselect_values.module.css +1 -0
- package/src/inputs/multiselect/multiselect_values.tsx +4 -4
- package/src/layouts/__stories__/columns.stories.tsx +31 -0
- package/src/layouts/__stories__/composed.stories.tsx +77 -8
- package/src/layouts/__stories__/rows.stories.tsx +77 -0
- package/src/layouts/__stories__/utils.tsx +2 -84
- package/src/layouts/containers/columns/column.module.css +3 -2
- package/src/layouts/containers/columns/columns.tsx +29 -3
- package/src/layouts/containers/containers.module.css +27 -29
- package/src/layouts/containers/rail.tsx +9 -51
- package/src/layouts/containers/rows/index.ts +2 -0
- package/src/layouts/containers/rows/row.module.css +15 -0
- package/src/layouts/containers/rows/row.tsx +22 -0
- package/src/layouts/containers/rows/rows.tsx +42 -0
- package/src/layouts/containers/scaffold.tsx +9 -49
- package/src/layouts/index.ts +2 -0
- package/src/overlay/frame/frame.stories.tsx +2 -1
- package/src/overlay/frame/frame.tsx +68 -20
- package/src/overlay/popper/base/dismissal_decorator.tsx +3 -3
- package/src/overlay/slide/slide.stories.tsx +1 -1
- package/src/stacks/box/box.tsx +29 -4
- package/src/stacks/box/detect_resize_bounds.ts +5 -1
- package/src/stacks/box/end_resize_handle.tsx +1 -1
- package/src/stacks/box/resize_handlers.ts +1 -1
- package/src/stacks/box/start_resize_handle.tsx +1 -1
- package/src/stacks/box/types.ts +3 -2
- package/src/stacks/collapsible_box.stories.tsx +5 -5
- package/src/stacks/demo.stories.tsx +7 -7
- package/src/surfaces/card/card.module.css +5 -0
- package/src/surfaces/card/card.stories.tsx +66 -8
- package/src/surfaces/card/card.tsx +6 -2
- package/src/surfaces/page/page.stories.tsx +84 -4
- package/src/surfaces/panel/__stories__/panel.stories.tsx +84 -9
- package/src/surfaces/window/window.stories.tsx +1 -1
- package/src/test-setup.ts +11 -0
- package/src/themes/stories/button_showcase.tsx +3 -1
- package/src/themes/stories/controls_fieldset.tsx +3 -1
- package/src/themes/stories/menu_showcase.tsx +3 -1
- package/src/themes/theme.tsx +6 -16
- package/src/themes/themes/ergo/INTERACTIVE.md +89 -0
- package/src/themes/themes/ergo/ROADMAP.md +116 -0
- package/src/themes/themes/ergo/ergo_theme.css +219 -734
- package/src/themes/themes/ergo/ergo_theme.ts +15 -1
- package/src/themes/themes/ergo/parts/actions.css +287 -0
- package/src/themes/themes/ergo/parts/base.css +62 -0
- package/src/themes/themes/ergo/parts/form.css +23 -0
- package/src/themes/themes/ergo/parts/inputs.css +252 -0
- package/src/themes/themes/ergo/parts/navigation.css +104 -0
- package/src/themes/themes/windows_98/windows_98.css +32 -43
- package/src/tokens/chip/chip.stories.tsx +5 -5
- package/src/utils/decorators/DECORATOR_PATTERN.md +86 -0
- package/src/utils/decorators/clone_with_decorator.ts +47 -0
- package/src/utils/{dnd → decorators/draggable}/__stories__/draggable.stories.tsx +7 -7
- package/src/utils/{dnd → decorators/draggable}/__stories__/use_draggable.stories.tsx +2 -2
- package/src/utils/{dnd/handle.tsx → decorators/draggable/drag_handle.tsx} +1 -1
- package/src/utils/{dnd → decorators}/draggable/draggable.tsx +2 -2
- package/src/utils/decorators/draggable/index.ts +15 -0
- package/src/utils/{dnd → decorators/draggable}/types.ts +1 -1
- package/src/utils/{dnd/hooks → decorators/draggable}/use_drag_container.ts +2 -2
- package/src/utils/decorators/index.ts +2 -0
- package/src/utils/decorators/resizable/__stories__/resizable.stories.tsx +214 -0
- package/src/utils/decorators/resizable/__stories__/resizable_stories.module.css +47 -0
- package/src/utils/decorators/resizable/__tests__/handle_config.test.ts +191 -0
- package/src/utils/decorators/resizable/__tests__/resize_strategy.test.ts +163 -0
- package/src/utils/decorators/resizable/context.ts +9 -0
- package/src/utils/decorators/resizable/handle_config.ts +118 -0
- package/src/utils/decorators/resizable/index.ts +37 -0
- package/src/utils/decorators/resizable/resizable.module.css +5 -0
- package/src/utils/decorators/resizable/resizable.tsx +97 -0
- package/src/utils/decorators/resizable/resize_handle.module.css +106 -0
- package/src/utils/decorators/resizable/resize_handle.tsx +165 -0
- package/src/utils/decorators/resizable/resize_strategy.ts +190 -0
- package/src/utils/decorators/resizable/types.ts +58 -0
- package/src/utils/hooks/labelled_by_context.ts +27 -0
- package/src/utils/index.ts +9 -7
- package/src/utils/{click_away_listener.tsx → listeners/click_away_listener.tsx} +1 -1
- package/src/utils/listeners/index.ts +3 -0
- package/src/utils/{scroll_away_listener.tsx → listeners/scroll_away_listener.tsx} +1 -1
- package/src/utils/system/index.ts +1 -0
- package/src/utils/types/sides.ts +2 -0
- package/dist/actions/button/slim_button/slim_button.d.ts +0 -9
- package/dist/actions/button/slim_button/slim_button.d.ts.map +0 -1
- package/dist/actions/button/slim_button/slim_button.js +0 -18
- package/dist/actions/button/slim_button/slim_button.js.map +0 -1
- package/dist/containers.module-DlGySre0.js +0 -5
- package/dist/containers.module-DlGySre0.js.map +0 -1
- package/dist/draggable.module-BgelQsuJ.js +0 -5
- package/dist/draggable.module-BgelQsuJ.js.map +0 -1
- package/dist/frame.css +0 -1
- package/dist/left_resize_handle.css +0 -1
- package/dist/right_resize_handle.css +0 -1
- package/dist/slim_button.css +0 -1
- package/dist/stacks/box/left_resize_handle.d.ts +0 -4
- package/dist/stacks/box/left_resize_handle.d.ts.map +0 -1
- package/dist/stacks/box/left_resize_handle.js +0 -36
- package/dist/stacks/box/left_resize_handle.js.map +0 -1
- package/dist/stacks/box/right_resize_handle.d.ts +0 -4
- package/dist/stacks/box/right_resize_handle.d.ts.map +0 -1
- package/dist/stacks/box/right_resize_handle.js +0 -36
- package/dist/stacks/box/right_resize_handle.js.map +0 -1
- package/dist/utils/click_away_listener.d.ts.map +0 -1
- package/dist/utils/click_away_listener.js.map +0 -1
- package/dist/utils/dnd/context.d.ts.map +0 -1
- package/dist/utils/dnd/context.js.map +0 -1
- package/dist/utils/dnd/draggable/draggable.d.ts.map +0 -1
- package/dist/utils/dnd/draggable/draggable.js.map +0 -1
- package/dist/utils/dnd/handle.d.ts.map +0 -1
- package/dist/utils/dnd/handle.js.map +0 -1
- package/dist/utils/dnd/hooks/use_drag_container.d.ts.map +0 -1
- package/dist/utils/dnd/hooks/use_drag_container.js.map +0 -1
- package/dist/utils/dnd/hooks/use_draggable.d.ts.map +0 -1
- package/dist/utils/dnd/hooks/use_draggable.js.map +0 -1
- package/dist/utils/dnd/types.d.ts.map +0 -1
- package/dist/utils/focus_redirect.d.ts.map +0 -1
- package/dist/utils/focus_redirect.js.map +0 -1
- package/dist/utils/mouse_leave_region.d.ts.map +0 -1
- package/dist/utils/mouse_leave_region.js.map +0 -1
- package/dist/utils/scroll_away_listener.d.ts.map +0 -1
- package/dist/utils/scroll_away_listener.js.map +0 -1
- package/dist/utils/types/variations.d.ts.map +0 -1
- package/src/actions/button/__stories__/slim_button.stories.tsx +0 -274
- package/src/actions/button/slim_button/slim_button.module.css +0 -9
- package/src/actions/button/slim_button/slim_button.tsx +0 -26
- package/src/overlay/frame/frame.module.css +0 -5
- package/src/stacks/box/left_resize_handle.module.css +0 -12
- package/src/stacks/box/left_resize_handle.tsx +0 -39
- package/src/stacks/box/right_resize_handle.module.css +0 -12
- package/src/stacks/box/right_resize_handle.tsx +0 -38
- /package/dist/utils/{dnd → decorators/draggable}/context.d.ts +0 -0
- /package/dist/utils/{dnd → decorators/draggable}/context.js +0 -0
- /package/dist/utils/{dnd → decorators}/draggable/draggable.d.ts +0 -0
- /package/dist/utils/{dnd → decorators/draggable}/types.js +0 -0
- /package/dist/utils/{dnd → decorators/draggable}/types.js.map +0 -0
- /package/dist/utils/{dnd/hooks → decorators/draggable}/use_drag_container.js +0 -0
- /package/dist/utils/{dnd/hooks → decorators/draggable}/use_draggable.d.ts +0 -0
- /package/dist/utils/{dnd/hooks → decorators/draggable}/use_draggable.js +0 -0
- /package/dist/utils/{click_away_listener.d.ts → listeners/click_away_listener.d.ts} +0 -0
- /package/dist/utils/{focus_redirect.d.ts → listeners/focus_redirect.d.ts} +0 -0
- /package/dist/utils/{focus_redirect.js → listeners/focus_redirect.js} +0 -0
- /package/dist/utils/{mouse_leave_region.d.ts → listeners/mouse_leave_region.d.ts} +0 -0
- /package/dist/utils/{mouse_leave_region.js → listeners/mouse_leave_region.js} +0 -0
- /package/dist/utils/{scroll_away_listener.d.ts → listeners/scroll_away_listener.d.ts} +0 -0
- /package/dist/utils/{types → system}/variations.d.ts +0 -0
- /package/src/utils/{dnd → decorators/draggable}/__stories__/draggable_stories.module.css +0 -0
- /package/src/utils/{dnd → decorators/draggable}/context.ts +0 -0
- /package/src/utils/{dnd → decorators}/draggable/draggable.module.css +0 -0
- /package/src/utils/{dnd/hooks → decorators/draggable}/use_draggable.ts +0 -0
- /package/src/utils/{click_away_listener.stories.tsx → listeners/click_away_listener.stories.tsx} +0 -0
- /package/src/utils/{focus_redirect.tsx → listeners/focus_redirect.tsx} +0 -0
- /package/src/utils/{mouse_leave_region.tsx → listeners/mouse_leave_region.tsx} +0 -0
- /package/src/utils/{scroll_away_listener.stories.tsx → listeners/scroll_away_listener.stories.tsx} +0 -0
- /package/src/utils/{types → system}/variations.ts +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
@layer tcn-theme {
|
|
2
|
+
/* ===== Tabs ===== */
|
|
3
|
+
.tcn-tabs-bar {
|
|
4
|
+
.tcn-tabs-list {
|
|
5
|
+
.tcn-tab-item {
|
|
6
|
+
min-height: 24px;
|
|
7
|
+
padding: 0px var(--padding-medium);
|
|
8
|
+
text-decoration: none;
|
|
9
|
+
text-overflow: ellipsis;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
white-space: nowrap;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* Default */
|
|
17
|
+
.tcn-tabs-bar[data-variant="default"] {
|
|
18
|
+
.tcn-tabs-list {
|
|
19
|
+
.tcn-tab-item {
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
border: none;
|
|
22
|
+
padding: 0px var(--padding-medium);
|
|
23
|
+
border-radius: 0;
|
|
24
|
+
}
|
|
25
|
+
.tcn-tab-item[data-is-selected="true"] {
|
|
26
|
+
--mat: var(--tcn-button-color, var(--material));
|
|
27
|
+
--ink: var(--tcn-button-text-color, var(--ergo-primary));
|
|
28
|
+
--act: var(--ergo-primary);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.tcn-tab-item:focus-visible {
|
|
32
|
+
z-index: 2;
|
|
33
|
+
}
|
|
34
|
+
/* Hover Indicator */
|
|
35
|
+
.tcn-tab-item[data-is-selected="false"]:hover::after,
|
|
36
|
+
.tcn-tab-item[data-is-selected="false"]:focus-visible::after {
|
|
37
|
+
content: "";
|
|
38
|
+
display: block;
|
|
39
|
+
position: absolute;
|
|
40
|
+
left: 0;
|
|
41
|
+
right: 0;
|
|
42
|
+
bottom: 0px;
|
|
43
|
+
height: 1px;
|
|
44
|
+
background: var(--ergo-accent-blue);
|
|
45
|
+
pointer-events: none;
|
|
46
|
+
width: 100%;
|
|
47
|
+
z-index: 3;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Indicator */
|
|
51
|
+
&::after {
|
|
52
|
+
content: "";
|
|
53
|
+
position: absolute;
|
|
54
|
+
bottom: -1px;
|
|
55
|
+
left: 0;
|
|
56
|
+
min-height: 2px;
|
|
57
|
+
transform: translateX(var(--tabs-active-rectangle-position-x, 0));
|
|
58
|
+
width: var(--tabs-active-rectangle-width, 0);
|
|
59
|
+
background: var(--ergo-primary);
|
|
60
|
+
pointer-events: none;
|
|
61
|
+
border-bottom-left-radius: 2px;
|
|
62
|
+
border-bottom-right-radius: 2px;
|
|
63
|
+
transition:
|
|
64
|
+
transform 300ms ease-in-out,
|
|
65
|
+
width 300ms ease-in-out;
|
|
66
|
+
will-change: transform, width;
|
|
67
|
+
z-index: 2;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Rail */
|
|
72
|
+
&::before {
|
|
73
|
+
content: "";
|
|
74
|
+
position: absolute;
|
|
75
|
+
bottom: 0px;
|
|
76
|
+
left: 0;
|
|
77
|
+
width: 100%;
|
|
78
|
+
height: 1px;
|
|
79
|
+
background: var(--ergo-material-divider);
|
|
80
|
+
pointer-events: none;
|
|
81
|
+
z-index: 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Inline */
|
|
86
|
+
.tcn-tabs-bar[data-variant="inline"] {
|
|
87
|
+
font-size: 12px;
|
|
88
|
+
min-width: min-content;
|
|
89
|
+
width: auto;
|
|
90
|
+
flex-grow: 0;
|
|
91
|
+
border-radius: 6px;
|
|
92
|
+
border: 1px solid var(--on-material);
|
|
93
|
+
padding: 2px;
|
|
94
|
+
|
|
95
|
+
.tcn-tabs-list {
|
|
96
|
+
height: 20px;
|
|
97
|
+
gap: var(--ergo-spacing-xs);
|
|
98
|
+
.tcn-tab-item {
|
|
99
|
+
border-radius: var(--ergo-shape-radius-medium);
|
|
100
|
+
min-height: 20px;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -112,6 +112,37 @@
|
|
|
112
112
|
outline: none;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
/* Utility button styles — selectors mirror hierarchy/hover combos above to win specificity */
|
|
116
|
+
.tcn-button[data-is-utility="true"],
|
|
117
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="primary"],
|
|
118
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="secondary"],
|
|
119
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="primary"]:hover,
|
|
120
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="secondary"]:hover {
|
|
121
|
+
padding: 2px;
|
|
122
|
+
min-width: 0;
|
|
123
|
+
min-height: 0;
|
|
124
|
+
height: auto;
|
|
125
|
+
width: auto;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.tcn-button[data-is-utility="true"][data-size="sm"],
|
|
129
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="primary"][data-size="sm"]:hover,
|
|
130
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="secondary"][data-size="sm"]:hover {
|
|
131
|
+
padding: 1px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.tcn-button[data-is-utility="true"][data-size="md"],
|
|
135
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="primary"][data-size="md"]:hover,
|
|
136
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="secondary"][data-size="md"]:hover {
|
|
137
|
+
padding: 2px;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.tcn-button[data-is-utility="true"][data-size="lg"],
|
|
141
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="primary"][data-size="lg"]:hover,
|
|
142
|
+
.tcn-button[data-is-utility="true"][data-hierarchy="secondary"][data-size="lg"]:hover {
|
|
143
|
+
padding: 4px;
|
|
144
|
+
}
|
|
145
|
+
|
|
115
146
|
.tcn-button[data-is-disabled="true"] {
|
|
116
147
|
text-shadow: 1px 1px 0 #fff;
|
|
117
148
|
}
|
|
@@ -289,43 +320,6 @@
|
|
|
289
320
|
pointer-events: none;
|
|
290
321
|
}
|
|
291
322
|
|
|
292
|
-
/* Slim button styles */
|
|
293
|
-
.tcn-slim-button,
|
|
294
|
-
.tcn-slim-button[data-hierarchy="primary"],
|
|
295
|
-
.tcn-slim-button[data-hierarchy="secondary"],
|
|
296
|
-
.tcn-slim-button[data-hierarchy="primary"]:hover,
|
|
297
|
-
.tcn-slim-button[data-hierarchy="secondary"]:hover {
|
|
298
|
-
padding: 2px;
|
|
299
|
-
min-width: 0;
|
|
300
|
-
min-height: 0;
|
|
301
|
-
height: auto;
|
|
302
|
-
width: auto;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
.tcn-slim-button[data-size="sm"],
|
|
306
|
-
.tcn-slim-button[data-hierarchy="primary"][data-size="sm"],
|
|
307
|
-
.tcn-slim-button[data-hierarchy="secondary"][data-size="sm"],
|
|
308
|
-
.tcn-slim-button[data-hierarchy="primary"][data-size="sm"]:hover,
|
|
309
|
-
.tcn-slim-button[data-hierarchy="secondary"][data-size="sm"]:hover {
|
|
310
|
-
padding: 1px;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
.tcn-slim-button[data-size="md"],
|
|
314
|
-
.tcn-slim-button[data-hierarchy="primary"][data-size="md"],
|
|
315
|
-
.tcn-slim-button[data-hierarchy="secondary"][data-size="md"],
|
|
316
|
-
.tcn-slim-button[data-hierarchy="primary"][data-size="md"]:hover,
|
|
317
|
-
.tcn-slim-button[data-hierarchy="secondary"][data-size="md"]:hover {
|
|
318
|
-
padding: 2px;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
.tcn-slim-button[data-size="lg"],
|
|
322
|
-
.tcn-slim-button[data-hierarchy="primary"][data-size="lg"],
|
|
323
|
-
.tcn-slim-button[data-hierarchy="secondary"][data-size="lg"],
|
|
324
|
-
.tcn-slim-button[data-hierarchy="primary"][data-size="lg"]:hover,
|
|
325
|
-
.tcn-slim-button[data-hierarchy="secondary"][data-size="lg"]:hover {
|
|
326
|
-
padding: 4px;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
323
|
/* Select group styles */
|
|
330
324
|
.tcn-select-group .tcn-button[data-hierarchy="primary"],
|
|
331
325
|
.tcn-select-group .tcn-button[data-hierarchy="primary"]:hover,
|
|
@@ -682,6 +676,7 @@
|
|
|
682
676
|
margin-top: 10px;
|
|
683
677
|
border-radius: 0;
|
|
684
678
|
background: #c0c0c0;
|
|
679
|
+
gap: 8px;
|
|
685
680
|
box-shadow:
|
|
686
681
|
inset 1px 1px #808080,
|
|
687
682
|
inset -1px -1px #f5f5f5,
|
|
@@ -689,12 +684,6 @@
|
|
|
689
684
|
inset -2px -2px #808080;
|
|
690
685
|
}
|
|
691
686
|
|
|
692
|
-
.tcn-field-set > .tcn-field-set-body {
|
|
693
|
-
background: transparent;
|
|
694
|
-
padding: 0;
|
|
695
|
-
gap: 8px;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
687
|
.tcn-field-set > .tcn-field-set-legend {
|
|
699
688
|
position: relative;
|
|
700
689
|
top: -7px;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { HStack } from '../../stacks/h_stack.js';
|
|
2
2
|
import { Spacer } from '../../stacks/spacer.js';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { Button } from '../../actions/index.js';
|
|
5
5
|
import { Chip } from './chip.js';
|
|
6
6
|
import { BodyText } from '../../typography/index.js';
|
|
7
7
|
import { CrossIcon } from '@tcn/icons/cross_icon.js';
|
|
@@ -21,9 +21,9 @@ export const WithIcon = () => (
|
|
|
21
21
|
<HStack>
|
|
22
22
|
<BodyText padStart="8px">Hola Mundo</BodyText>
|
|
23
23
|
<Spacer width="8px" />
|
|
24
|
-
<
|
|
24
|
+
<Button utility size="sm" hierarchy="tertiary">
|
|
25
25
|
<CrossIcon size="sm" />
|
|
26
|
-
</
|
|
26
|
+
</Button>
|
|
27
27
|
</HStack>
|
|
28
28
|
</Chip>
|
|
29
29
|
);
|
|
@@ -40,9 +40,9 @@ export const AllVariations = () => (
|
|
|
40
40
|
// <HStack>
|
|
41
41
|
// <BodyText padStart="8px">Hola Mundo</BodyText>
|
|
42
42
|
// <Spacer width="8px" />
|
|
43
|
-
// <
|
|
43
|
+
// <Button utility size="sm" hierarchy="tertiary">
|
|
44
44
|
// <CrossIcon size="sm" />
|
|
45
|
-
// </
|
|
45
|
+
// </Button>
|
|
46
46
|
// </HStack>
|
|
47
47
|
// </Chip>
|
|
48
48
|
// }
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Decorator Pattern
|
|
2
|
+
|
|
3
|
+
Decorators are components that wrap exactly one child element via `React.cloneElement`, inject behavior (props, refs, classNames, CSS variables), and provide a context for sub-components (handles, controls).
|
|
4
|
+
|
|
5
|
+
## What Makes a Decorator
|
|
6
|
+
|
|
7
|
+
- Wraps a single child element using `cloneElement`
|
|
8
|
+
- Injects props onto the child without the child's knowledge
|
|
9
|
+
- Can provide a React context consumed by sub-components (e.g. `ResizeHandle` reads `ResizableContext`)
|
|
10
|
+
- Is composable by stacking: `<Draggable><Resizable><div /></Resizable></Draggable>`
|
|
11
|
+
|
|
12
|
+
Decorators are distinct from **listeners** (which monitor external events like clicks-outside or scrolls without using `cloneElement`).
|
|
13
|
+
|
|
14
|
+
## cloneElement Rules
|
|
15
|
+
|
|
16
|
+
When cloning the child element:
|
|
17
|
+
|
|
18
|
+
1. **Merge `className`** via `clsx` -- never replace the child's existing classes
|
|
19
|
+
2. **Fork `ref`** via `useForkRef` -- preserve both the decorator's internal ref and the consumer's forwarded ref
|
|
20
|
+
3. **Spread `style`** -- merge into the child's existing style, never replace
|
|
21
|
+
4. **Use `tcn-*` CSS class** -- add a `tcn-<decorator-name>` class for external styling hooks
|
|
22
|
+
5. **Use `data-*` attributes** for state (`data-is-dragging`, `data-is-resizable`, etc.)
|
|
23
|
+
|
|
24
|
+
The shared utility `clone_with_decorator.ts` consolidates this boilerplate.
|
|
25
|
+
|
|
26
|
+
## Context Pattern
|
|
27
|
+
|
|
28
|
+
Each decorator provides its own context:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
// context.ts
|
|
32
|
+
export const ResizableContext = createContext<ResizableContextValue | undefined>(undefined);
|
|
33
|
+
export const useResizable = makeContextHook(ResizableContext, 'ResizableContext');
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Sub-components (handles, controls) consume this context to coordinate with their parent decorator.
|
|
37
|
+
|
|
38
|
+
## displayName Discrimination
|
|
39
|
+
|
|
40
|
+
When a decorator needs to separate its own sub-components from other children, use `displayName` matching:
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
function isResizeHandle(child: React.ReactNode): boolean {
|
|
44
|
+
return (type as { displayName?: string }).displayName === 'ResizeHandle';
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Always set `displayName` on sub-components. Note: wrapping a sub-component in a HOC can break `displayName` matching -- keep sub-components as direct exports.
|
|
49
|
+
|
|
50
|
+
## Stacking Decorators
|
|
51
|
+
|
|
52
|
+
Decorators compose cleanly by stacking:
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
<Draggable>
|
|
56
|
+
<Resizable>
|
|
57
|
+
<div>content</div>
|
|
58
|
+
</Resizable>
|
|
59
|
+
</Draggable>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This works because:
|
|
63
|
+
- Each decorator forks the ref chain independently via `useForkRef`
|
|
64
|
+
- Props are merged (className via clsx, style via spread), not replaced
|
|
65
|
+
- Each decorator provides its own isolated context
|
|
66
|
+
|
|
67
|
+
No optimization for single-`cloneElement` composition is needed -- `cloneElement` is synchronous and cheap.
|
|
68
|
+
|
|
69
|
+
## Creating a New Decorator
|
|
70
|
+
|
|
71
|
+
Checklist:
|
|
72
|
+
|
|
73
|
+
1. Create a directory under `utils/decorators/<name>/`
|
|
74
|
+
2. Use `cloneWithDecorator()` from `clone_with_decorator.ts` for the cloneElement boilerplate
|
|
75
|
+
3. (Optional) Create a context + `makeContextHook` for sub-component communication
|
|
76
|
+
4. Set `displayName` on all sub-components
|
|
77
|
+
5. Add `tcn-<name>` CSS class on the target element
|
|
78
|
+
6. Add `data-*` attributes for observable state
|
|
79
|
+
7. Write stories for solo usage and stacked usage with other decorators
|
|
80
|
+
8. Export from the decorator's `index.ts` barrel
|
|
81
|
+
9. Re-export from `utils/decorators/index.ts`
|
|
82
|
+
|
|
83
|
+
## Current Decorators
|
|
84
|
+
|
|
85
|
+
- **Resizable** (`decorators/resizable/`) -- makes an element resizable via drag handles
|
|
86
|
+
- **Draggable** (`decorators/draggable/`) -- makes an element draggable via drag handles
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ClassValue } from 'clsx';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shared utility for decorator-pattern components that wrap a child via cloneElement.
|
|
7
|
+
*
|
|
8
|
+
* Consolidates the boilerplate: merges className via clsx, spreads style,
|
|
9
|
+
* accepts a pre-forked ref (callers must invoke useForkRef themselves),
|
|
10
|
+
* and optionally appends extra children (e.g. handles).
|
|
11
|
+
*
|
|
12
|
+
* Internal only — not exported from the package.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
interface DecoratorProps {
|
|
16
|
+
className?: ClassValue;
|
|
17
|
+
style?: React.CSSProperties;
|
|
18
|
+
ref?: React.Ref<unknown>;
|
|
19
|
+
children?: React.ReactNode;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function cloneWithDecorator(
|
|
24
|
+
child: React.ReactElement,
|
|
25
|
+
injectedProps: DecoratorProps,
|
|
26
|
+
extraChildren?: React.ReactNode[]
|
|
27
|
+
): React.ReactElement {
|
|
28
|
+
const { className, style, ref, children, ...rest } = injectedProps;
|
|
29
|
+
|
|
30
|
+
const mergedProps: Record<string, unknown> = {
|
|
31
|
+
...rest,
|
|
32
|
+
className: clsx(child.props.className, className),
|
|
33
|
+
style: { ...child.props.style, ...(style as object) },
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
if (ref !== undefined) {
|
|
37
|
+
mergedProps.ref = ref;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const childContent = children ?? child.props.children;
|
|
41
|
+
|
|
42
|
+
if (extraChildren && extraChildren.length > 0) {
|
|
43
|
+
return React.cloneElement(child, mergedProps, childContent, ...extraChildren);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return React.cloneElement(child, mergedProps);
|
|
47
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Button } from '
|
|
2
|
-
import { Box } from '
|
|
3
|
-
import { VStack } from '
|
|
4
|
-
import { ZStack } from '
|
|
5
|
-
import { BodyText } from '
|
|
1
|
+
import { Button } from '../../../../actions/button/button/button.js';
|
|
2
|
+
import { Box } from '../../../../stacks/box/box.js';
|
|
3
|
+
import { VStack } from '../../../../stacks/v_stack.js';
|
|
4
|
+
import { ZStack } from '../../../../stacks/z_stack.js';
|
|
5
|
+
import { BodyText } from '../../../../typography/index.js';
|
|
6
6
|
import { useDragContainer } from '../context.js';
|
|
7
|
-
import { Draggable } from '../draggable
|
|
8
|
-
import { DragHandle } from '../
|
|
7
|
+
import { Draggable } from '../draggable.js';
|
|
8
|
+
import { DragHandle } from '../drag_handle.js';
|
|
9
9
|
import styles from './draggable_stories.module.css';
|
|
10
10
|
|
|
11
11
|
export default {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useRef } from 'react';
|
|
2
|
-
import { useDraggable } from '../
|
|
3
|
-
import { Box } from '
|
|
2
|
+
import { useDraggable } from '../use_draggable.js';
|
|
3
|
+
import { Box } from '../../../../stacks/box/box.js';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
title: 'Utils/useDraggable',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { useDragContainer } from './context.js';
|
|
4
|
-
import { useForkRef } from '
|
|
4
|
+
import { useForkRef } from '../../hooks/use_fork_ref.js';
|
|
5
5
|
|
|
6
6
|
export interface DragHandleProps {
|
|
7
7
|
children: React.ReactElement;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useMemo, type CSSProperties } from 'react';
|
|
2
2
|
|
|
3
|
-
import { DragContainerContext } from '
|
|
3
|
+
import { DragContainerContext } from './context.js';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
-
import { useMakeDragContainer } from '
|
|
5
|
+
import { useMakeDragContainer } from './use_drag_container.js';
|
|
6
6
|
|
|
7
7
|
import styles from './draggable.module.css';
|
|
8
8
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { Draggable } from './draggable.js';
|
|
2
|
+
export type { DraggableProps } from './draggable.js';
|
|
3
|
+
|
|
4
|
+
export { DragHandle } from './drag_handle.js';
|
|
5
|
+
export type { DragHandleProps } from './drag_handle.js';
|
|
6
|
+
|
|
7
|
+
export { useDragContainer, DragContainerContext } from './context.js';
|
|
8
|
+
|
|
9
|
+
export { useDraggable } from './use_draggable.js';
|
|
10
|
+
export type { UseDraggableOptions } from './use_draggable.js';
|
|
11
|
+
|
|
12
|
+
export { useMakeDragContainer } from './use_drag_container.js';
|
|
13
|
+
export type { UseDragContainerOptions } from './use_drag_container.js';
|
|
14
|
+
|
|
15
|
+
export type { DragContainer } from './types.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback, useRef, useState } from 'react';
|
|
2
|
-
import type { Position } from '../../
|
|
3
|
-
import type { DragContainer } from '
|
|
2
|
+
import type { Position } from '../../types/dimensions.js';
|
|
3
|
+
import type { DragContainer } from './types.js';
|
|
4
4
|
import { useDraggable } from './use_draggable.js';
|
|
5
5
|
|
|
6
6
|
export interface UseDragContainerOptions {
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
import { Resizable } from '../resizable.js';
|
|
3
|
+
import { ResizeHandle } from '../resize_handle.js';
|
|
4
|
+
import { Box } from '../../../../stacks/box/box.js';
|
|
5
|
+
import { VStack } from '../../../../stacks/v_stack.js';
|
|
6
|
+
import { BodyText } from '../../../../typography/index.js';
|
|
7
|
+
import styles from './resizable_stories.module.css';
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: 'Utils/Resizable',
|
|
11
|
+
component: Resizable,
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const HorizontalResize = () => {
|
|
16
|
+
const [width, setWidth] = useState(300);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<VStack gap="8px" padding="16px" minHeight="400px">
|
|
20
|
+
<BodyText>Drag the end edge to resize horizontally.</BodyText>
|
|
21
|
+
<Resizable onWidthResize={({ width: w }) => setWidth(Math.round(w))}>
|
|
22
|
+
<Box width={`${width}px`} height="200px" className={styles['demo-box']}>
|
|
23
|
+
<BodyText>Resizable content</BodyText>
|
|
24
|
+
<div className={styles['size-display']}>width: {width}px</div>
|
|
25
|
+
</Box>
|
|
26
|
+
<ResizeHandle position="end" className={styles['demo-handle']} />
|
|
27
|
+
</Resizable>
|
|
28
|
+
</VStack>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const VerticalResize = () => {
|
|
33
|
+
const [height, setHeight] = useState(200);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<VStack gap="8px" padding="16px" minHeight="600px">
|
|
37
|
+
<BodyText>Drag the bottom edge to resize vertically.</BodyText>
|
|
38
|
+
<Resizable onHeightResize={({ height: h }) => setHeight(Math.round(h))}>
|
|
39
|
+
<Box width="400px" height={`${height}px`} className={styles['demo-box']}>
|
|
40
|
+
<BodyText>Resizable content</BodyText>
|
|
41
|
+
<div className={styles['size-display']}>height: {height}px</div>
|
|
42
|
+
</Box>
|
|
43
|
+
<ResizeHandle position="bottom" className={styles['demo-handle']} />
|
|
44
|
+
</Resizable>
|
|
45
|
+
</VStack>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const CornerResize = () => {
|
|
50
|
+
const [width, setWidth] = useState(300);
|
|
51
|
+
const [height, setHeight] = useState(200);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<VStack gap="8px" padding="16px" minHeight="600px">
|
|
55
|
+
<BodyText>
|
|
56
|
+
Drag the bottom-right corner to resize both axes simultaneously.
|
|
57
|
+
</BodyText>
|
|
58
|
+
<Resizable
|
|
59
|
+
onWidthResize={({ width: w }) => setWidth(Math.round(w))}
|
|
60
|
+
onHeightResize={({ height: h }) => setHeight(Math.round(h))}
|
|
61
|
+
>
|
|
62
|
+
<Box width={`${width}px`} height={`${height}px`} className={styles['demo-box']}>
|
|
63
|
+
<BodyText>Resizable content</BodyText>
|
|
64
|
+
<div className={styles['size-display']}>
|
|
65
|
+
{width}px × {height}px
|
|
66
|
+
</div>
|
|
67
|
+
</Box>
|
|
68
|
+
<ResizeHandle position="bottom-end" className={styles['demo-handle']} />
|
|
69
|
+
</Resizable>
|
|
70
|
+
</VStack>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const MultipleHandles = () => {
|
|
75
|
+
const [width, setWidth] = useState(400);
|
|
76
|
+
const [height, setHeight] = useState(300);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<VStack gap="8px" padding="16px" minHeight="600px">
|
|
80
|
+
<BodyText>Start, end, bottom edges and bottom-end corner — all active.</BodyText>
|
|
81
|
+
<Resizable
|
|
82
|
+
onWidthResize={({ width: w }) => setWidth(Math.round(w))}
|
|
83
|
+
onHeightResize={({ height: h }) => setHeight(Math.round(h))}
|
|
84
|
+
>
|
|
85
|
+
<Box width={`${width}px`} height={`${height}px`} className={styles['demo-box']}>
|
|
86
|
+
<BodyText>Resizable content</BodyText>
|
|
87
|
+
<div className={styles['size-display']}>
|
|
88
|
+
{width}px × {height}px
|
|
89
|
+
</div>
|
|
90
|
+
</Box>
|
|
91
|
+
<ResizeHandle position="start" className={styles['demo-handle']} />
|
|
92
|
+
<ResizeHandle position="end" className={styles['demo-handle']} />
|
|
93
|
+
<ResizeHandle position="bottom" className={styles['demo-handle']} />
|
|
94
|
+
<ResizeHandle
|
|
95
|
+
position="bottom-end"
|
|
96
|
+
className={styles['demo-handle']}
|
|
97
|
+
style={{
|
|
98
|
+
zIndex: 2,
|
|
99
|
+
}}
|
|
100
|
+
/>
|
|
101
|
+
</Resizable>
|
|
102
|
+
</VStack>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const RTL = () => {
|
|
107
|
+
const [widthStart, setWidthStart] = useState(300);
|
|
108
|
+
const [widthEnd, setWidthEnd] = useState(300);
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<VStack gap="16px" padding="16px" minHeight="400px">
|
|
112
|
+
<BodyText>
|
|
113
|
+
RTL context: "start" flips to the right edge, "end" flips to
|
|
114
|
+
the left edge.
|
|
115
|
+
</BodyText>
|
|
116
|
+
<div className={styles['rtl-container']}>
|
|
117
|
+
<VStack gap="16px">
|
|
118
|
+
<BodyText>position="start" (flips to right edge in RTL)</BodyText>
|
|
119
|
+
<Resizable onWidthResize={({ width: w }) => setWidthStart(Math.round(w))}>
|
|
120
|
+
<Box width={`${widthStart}px`} height="100px" className={styles['demo-box']}>
|
|
121
|
+
<div className={styles['size-display']}>start handle: {widthStart}px</div>
|
|
122
|
+
</Box>
|
|
123
|
+
<ResizeHandle position="start" className={styles['demo-handle']} />
|
|
124
|
+
</Resizable>
|
|
125
|
+
|
|
126
|
+
<BodyText>position="end" (flips to left edge in RTL)</BodyText>
|
|
127
|
+
<Resizable onWidthResize={({ width: w }) => setWidthEnd(Math.round(w))}>
|
|
128
|
+
<Box width={`${widthEnd}px`} height="100px" className={styles['demo-box']}>
|
|
129
|
+
<div className={styles['size-display']}>end handle: {widthEnd}px</div>
|
|
130
|
+
</Box>
|
|
131
|
+
<ResizeHandle position="end" className={styles['demo-handle']} />
|
|
132
|
+
</Resizable>
|
|
133
|
+
</VStack>
|
|
134
|
+
</div>
|
|
135
|
+
</VStack>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export const NestedResizable = () => {
|
|
140
|
+
const [outerWidth, setOuterWidth] = useState(500);
|
|
141
|
+
const [innerWidth, setInnerWidth] = useState(250);
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<VStack gap="8px" padding="16px" minHeight="400px">
|
|
145
|
+
<BodyText>Nested: each handle binds to its nearest Resizable provider.</BodyText>
|
|
146
|
+
<Resizable onWidthResize={({ width: w }) => setOuterWidth(Math.round(w))}>
|
|
147
|
+
<Box width={`${outerWidth}px`} height="300px" className={styles['nested-outer']}>
|
|
148
|
+
<BodyText>Outer ({outerWidth}px)</BodyText>
|
|
149
|
+
<Resizable onWidthResize={({ width: w }) => setInnerWidth(Math.round(w))}>
|
|
150
|
+
<Box
|
|
151
|
+
width={`${innerWidth}px`}
|
|
152
|
+
height="150px"
|
|
153
|
+
className={styles['nested-inner']}
|
|
154
|
+
>
|
|
155
|
+
<BodyText>Inner ({innerWidth}px)</BodyText>
|
|
156
|
+
</Box>
|
|
157
|
+
<ResizeHandle position="end" className={styles['demo-handle']} />
|
|
158
|
+
</Resizable>
|
|
159
|
+
</Box>
|
|
160
|
+
<ResizeHandle position="end" className={styles['demo-handle']} />
|
|
161
|
+
</Resizable>
|
|
162
|
+
</VStack>
|
|
163
|
+
);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const OverflowHidden = () => {
|
|
167
|
+
const [width, setWidth] = useState(300);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<VStack gap="8px" padding="16px" minHeight="400px">
|
|
171
|
+
<BodyText>
|
|
172
|
+
Outer box is the resize target (minWidth: 100px). Inner box clips content with
|
|
173
|
+
overflow:hidden. Shrink below 200px to clip the purple box. It stops at 100px due
|
|
174
|
+
to the min-width constraint.
|
|
175
|
+
</BodyText>
|
|
176
|
+
<Resizable onWidthResize={({ width: w }) => setWidth(Math.round(w))}>
|
|
177
|
+
<Box width={`${width}px`} minWidth="100px" height="200px">
|
|
178
|
+
<Box height="100%" overflow="hidden" className={styles['demo-box']}>
|
|
179
|
+
<Box minWidth="200px" height="80px" className={styles['clip-target']} />
|
|
180
|
+
<div className={styles['size-display']}>width: {width}px</div>
|
|
181
|
+
</Box>
|
|
182
|
+
</Box>
|
|
183
|
+
<ResizeHandle position="end" className={styles['demo-handle']} />
|
|
184
|
+
</Resizable>
|
|
185
|
+
</VStack>
|
|
186
|
+
);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const CustomHandle = () => {
|
|
190
|
+
const handleRef = useRef<HTMLDivElement>(null);
|
|
191
|
+
const [width, setWidth] = useState(300);
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
<VStack gap="8px" padding="16px" minHeight="400px">
|
|
195
|
+
<BodyText>Custom styled handle with forwarded ref and aria attributes.</BodyText>
|
|
196
|
+
<Resizable onWidthResize={({ width: w }) => setWidth(Math.round(w))}>
|
|
197
|
+
<Box width={`${width}px`} height="200px" className={styles['demo-box']}>
|
|
198
|
+
<BodyText>Resizable content</BodyText>
|
|
199
|
+
<div className={styles['size-display']}>width: {width}px</div>
|
|
200
|
+
</Box>
|
|
201
|
+
<ResizeHandle
|
|
202
|
+
ref={handleRef}
|
|
203
|
+
position="end"
|
|
204
|
+
style={{
|
|
205
|
+
background: 'rgba(234, 67, 53, 0.4)',
|
|
206
|
+
width: '8px',
|
|
207
|
+
}}
|
|
208
|
+
aria-label="Resize handle"
|
|
209
|
+
data-testid="custom-handle"
|
|
210
|
+
/>
|
|
211
|
+
</Resizable>
|
|
212
|
+
</VStack>
|
|
213
|
+
);
|
|
214
|
+
};
|