From 3d6b72a169868e3b3cf6b105ef89aaaa211625b3 Mon Sep 17 00:00:00 2001 From: Andrey Yamanov Date: Tue, 4 Nov 2025 15:32:12 +0100 Subject: [PATCH] feat(Root): cursor strategy support --- .changeset/unlucky-tables-relax.md | 5 +++++ src/components/HiddenInput.tsx | 2 +- src/components/Root.tsx | 4 +++- src/components/actions/Action/Action.tsx | 2 +- src/components/actions/Button/Button.tsx | 6 ++++-- src/components/actions/ItemAction/ItemAction.tsx | 2 +- src/components/content/CopyPasteBlock/CopyPasteBlock.tsx | 2 +- src/components/content/Item/Item.tsx | 3 ++- src/components/fields/Checkbox/Checkbox.tsx | 2 +- src/components/fields/FileInput/FileInput.tsx | 4 ++-- src/components/fields/ListBox/ListBox.tsx | 2 +- src/components/fields/Slider/elements.ts | 2 +- src/components/fields/Switch/Switch.tsx | 4 ++-- src/components/organisms/FileTabs/FileTabs.tsx | 2 +- src/components/other/Base64Upload/Base64Upload.tsx | 4 ++-- src/components/other/Calendar/CalendarCell.tsx | 2 +- src/components/overlays/Tooltip/Tooltip.stories.tsx | 4 ++-- src/stories/CreateComponent.docs.mdx | 2 +- 18 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 .changeset/unlucky-tables-relax.md diff --git a/.changeset/unlucky-tables-relax.md b/.changeset/unlucky-tables-relax.md new file mode 100644 index 000000000..4e4a7cf29 --- /dev/null +++ b/.changeset/unlucky-tables-relax.md @@ -0,0 +1,5 @@ +--- +"@cube-dev/ui-kit": minor +--- + +Allow to set cursorStrategy to `web` or `native` in Root component. diff --git a/src/components/HiddenInput.tsx b/src/components/HiddenInput.tsx index 1f35a374f..769db6261 100644 --- a/src/components/HiddenInput.tsx +++ b/src/components/HiddenInput.tsx @@ -19,7 +19,7 @@ export const HiddenInput = tasty({ height: '100%', cursor: { '': 'default', - button: 'pointer', + button: '$pointer', disabled: 'not-allowed', }, }, diff --git a/src/components/Root.tsx b/src/components/Root.tsx index c14ac10a5..856693f4a 100644 --- a/src/components/Root.tsx +++ b/src/components/Root.tsx @@ -24,7 +24,6 @@ import { PortalProvider } from './portal'; const RootElement = tasty({ id: 'cube-ui-kit-root', - // className: 'root', }); const DEFAULT_STYLES = { @@ -49,6 +48,7 @@ export interface CubeRootProps extends BaseProps { monospaceFont?: string; applyLegacyTokens?: boolean; tracking?: TrackingProps; + cursorStrategy?: 'web' | 'native'; } const IS_DVH_SUPPORTED = @@ -70,6 +70,7 @@ export function Root(allProps: CubeRootProps) { monospaceFont, applyLegacyTokens, tracking, + cursorStrategy = 'web', style, ...props } = allProps; @@ -138,6 +139,7 @@ export function Root(allProps: CubeRootProps) { '--cube-dynamic-viewport-height': height ? height + 'px' : '100dvh', + '--pointer': cursorStrategy === 'web' ? 'pointer' : 'default', ...style, }} > diff --git a/src/components/actions/Action/Action.tsx b/src/components/actions/Action/Action.tsx index aa2049e75..128da4fe5 100644 --- a/src/components/actions/Action/Action.tsx +++ b/src/components/actions/Action/Action.tsx @@ -39,7 +39,7 @@ const ActionElement = tasty({ padding: 0, outline: 0, transition: 'theme', - cursor: 'pointer', + cursor: '$pointer', textDecoration: 'none', fill: '#clear', }, diff --git a/src/components/actions/Button/Button.tsx b/src/components/actions/Button/Button.tsx index f5476dbcd..ab377ca8c 100644 --- a/src/components/actions/Button/Button.tsx +++ b/src/components/actions/Button/Button.tsx @@ -100,8 +100,10 @@ export const DEFAULT_BUTTON_STYLES = { margin: 0, boxSizing: 'border-box', cursor: { - '': 'pointer', - disabled: 'default', + '': 'default', + ':is(a)': 'pointer', + ':is(button)': '$pointer', + disabled: 'not-allowed', }, gap: { '': '.75x', diff --git a/src/components/actions/ItemAction/ItemAction.tsx b/src/components/actions/ItemAction/ItemAction.tsx index d3d2a29ed..382a8685c 100644 --- a/src/components/actions/ItemAction/ItemAction.tsx +++ b/src/components/actions/ItemAction/ItemAction.tsx @@ -77,7 +77,7 @@ const ItemActionElement = tasty({ reset: 'button', outline: 0, outlineOffset: 1, - cursor: { '': 'pointer', disabled: 'default' }, + cursor: { '': '$pointer', disabled: 'default' }, padding: { '': '0 $inline-padding', 'with-icon': 0, diff --git a/src/components/content/CopyPasteBlock/CopyPasteBlock.tsx b/src/components/content/CopyPasteBlock/CopyPasteBlock.tsx index c1df47aa2..ed3c05255 100644 --- a/src/components/content/CopyPasteBlock/CopyPasteBlock.tsx +++ b/src/components/content/CopyPasteBlock/CopyPasteBlock.tsx @@ -60,7 +60,7 @@ const CopyPasteBlockElement = tasty(Card, { ':focus': '2px dashed #purple-text', error: 'dashed #danger', }, - cursor: 'pointer', + cursor: '$pointer', preset: { '': 't3', '[data-size="large"]': 't2', diff --git a/src/components/content/Item/Item.tsx b/src/components/content/Item/Item.tsx index f19b08592..e2ec64ac3 100644 --- a/src/components/content/Item/Item.tsx +++ b/src/components/content/Item/Item.tsx @@ -280,7 +280,8 @@ const ItemElement = tasty({ outlineOffset: 1, cursor: { '': 'default', - ':is(button) | :is(a)': 'pointer', + ':is(a)': 'pointer', + ':is(button) | listboxitem | menuitem': '$pointer', disabled: 'not-allowed', }, diff --git a/src/components/fields/Checkbox/Checkbox.tsx b/src/components/fields/Checkbox/Checkbox.tsx index 0d22b1e3c..b5710cfe4 100644 --- a/src/components/fields/Checkbox/Checkbox.tsx +++ b/src/components/fields/Checkbox/Checkbox.tsx @@ -64,7 +64,7 @@ const CheckboxWrapperElement = tasty({ gap: '1x', flow: 'row', preset: 'default', - cursor: 'pointer', + cursor: '$pointer', width: 'max max-content', color: '#dark-02', }, diff --git a/src/components/fields/FileInput/FileInput.tsx b/src/components/fields/FileInput/FileInput.tsx index b6109aa20..a87595a5b 100644 --- a/src/components/fields/FileInput/FileInput.tsx +++ b/src/components/fields/FileInput/FileInput.tsx @@ -43,7 +43,7 @@ const FileInputElement = tasty(Action, { }, border: true, radius: true, - cursor: 'pointer', + cursor: '$pointer', overflow: 'hidden', whiteSpace: 'nowrap', @@ -91,7 +91,7 @@ const FileInputElement = tasty(Action, { left: 0, radius: '$content-radius', opacity: 0.01, - cursor: 'pointer', + cursor: '$pointer', zIndex: 10, }, }, diff --git a/src/components/fields/ListBox/ListBox.tsx b/src/components/fields/ListBox/ListBox.tsx index 3a2de48c1..cac1beb98 100644 --- a/src/components/fields/ListBox/ListBox.tsx +++ b/src/components/fields/ListBox/ListBox.tsx @@ -191,7 +191,7 @@ const ListBoxCheckboxWrapper = tasty({ display: 'grid', placeItems: 'center', placeContent: 'center', - cursor: 'pointer', + cursor: '$pointer', placeSelf: 'stretch', }, }); diff --git a/src/components/fields/Slider/elements.ts b/src/components/fields/Slider/elements.ts index e57c79253..032384667 100644 --- a/src/components/fields/Slider/elements.ts +++ b/src/components/fields/Slider/elements.ts @@ -13,7 +13,7 @@ export const SliderThumbElement = tasty({ dragged: '#purple', disabled: '#dark-04', }, - cursor: 'pointer', + cursor: '$pointer', outline: { '': '#purple-text.0', focused: '1bw #purple-text', diff --git a/src/components/fields/Switch/Switch.tsx b/src/components/fields/Switch/Switch.tsx index fb53f91f6..351505a07 100644 --- a/src/components/fields/Switch/Switch.tsx +++ b/src/components/fields/Switch/Switch.tsx @@ -82,7 +82,7 @@ const SwitchElement = tasty({ }, outlineOffset: 1, transition: 'theme', - cursor: 'pointer', + cursor: '$pointer', Thumb: { position: 'absolute', @@ -116,7 +116,7 @@ const SwitchElement = tasty({ 'checked & [data-size="small"]': '1.25x', }, transition: 'left, theme', - cursor: 'pointer', + cursor: '$pointer', }, }, }); diff --git a/src/components/organisms/FileTabs/FileTabs.tsx b/src/components/organisms/FileTabs/FileTabs.tsx index 24faa07cb..c9e91bc9e 100644 --- a/src/components/organisms/FileTabs/FileTabs.tsx +++ b/src/components/organisms/FileTabs/FileTabs.tsx @@ -102,7 +102,7 @@ const TabElement = tasty(Action, { 'disabled, hovered, hovered & disabled': '#dark', }, cursor: { - '': 'pointer', + '': '$pointer', disabled: 'default', }, fontWeight: 500, diff --git a/src/components/other/Base64Upload/Base64Upload.tsx b/src/components/other/Base64Upload/Base64Upload.tsx index 8c38c27b8..ad649a70c 100644 --- a/src/components/other/Base64Upload/Base64Upload.tsx +++ b/src/components/other/Base64Upload/Base64Upload.tsx @@ -122,7 +122,7 @@ export const Base64Upload = styled( }), )` appearance: none; - cursor: pointer; + cursor: var(--pointer); outline: none; & input { @@ -132,7 +132,7 @@ export const Base64Upload = styled( bottom: 0; left: 0; opacity: 0; - cursor: pointer; + cursor: var(--pointer); width: 100%; height: 100%; } diff --git a/src/components/other/Calendar/CalendarCell.tsx b/src/components/other/Calendar/CalendarCell.tsx index 9eb21bf08..f39a5d403 100644 --- a/src/components/other/Calendar/CalendarCell.tsx +++ b/src/components/other/Calendar/CalendarCell.tsx @@ -40,7 +40,7 @@ const CalendarButtonElement = tasty({ }, outlineOffset: 0.5, radius: true, - cursor: 'pointer', + cursor: '$pointer', }, }); diff --git a/src/components/overlays/Tooltip/Tooltip.stories.tsx b/src/components/overlays/Tooltip/Tooltip.stories.tsx index 51d5ca2aa..0fbc40486 100644 --- a/src/components/overlays/Tooltip/Tooltip.stories.tsx +++ b/src/components/overlays/Tooltip/Tooltip.stories.tsx @@ -109,7 +109,7 @@ const FunctionPatternTemplate: Story = (args) => ( padding: '8px 16px', border: '2px solid #007acc', borderRadius: '4px', - cursor: 'pointer', + cursor: '$pointer', display: 'inline-block', backgroundColor: '#f0f8ff', color: '#333', @@ -154,7 +154,7 @@ const DirectFunctionPatternTemplate: Story = ( padding: '4px 8px', border: '1px solid #ff6b6b', borderRadius: '4px', - cursor: 'pointer', + cursor: '$pointer', display: 'inline-block', backgroundColor: '#ffe0e0', }} diff --git a/src/stories/CreateComponent.docs.mdx b/src/stories/CreateComponent.docs.mdx index b6404dee1..3370db872 100644 --- a/src/stories/CreateComponent.docs.mdx +++ b/src/stories/CreateComponent.docs.mdx @@ -314,7 +314,7 @@ const DEFAULT_ACTION_STYLES: Styles = { focused: '#purple-03', }, transition: 'theme', - cursor: 'pointer', + cursor: '$pointer', textDecoration: 'none', fill: '#clear', } as const;