From 4406e667e471849366a835b41327e77541ae8c9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Korczak?= Date: Mon, 16 Oct 2023 17:58:33 +0200 Subject: [PATCH] refactor: merge slider to range slider (#927) Co-authored-by: Segun Adebayo --- .changeset/slimy-ads-build.md | 10 + .xstate/slider.js | 55 +- e2e/slider.e2e.ts | 8 +- examples/next-ts/CHANGELOG.md | 2 +- examples/next-ts/package.json | 5 +- examples/next-ts/pages/range-slider.tsx | 10 +- examples/next-ts/pages/slider.tsx | 9 +- examples/nuxt-ts/package.json | 5 +- examples/nuxt-ts/pages/range-slider.vue | 10 +- examples/nuxt-ts/pages/slider.vue | 7 +- examples/shadow-dom/package.json | 5 +- examples/solid-ts/CHANGELOG.md | 2 +- examples/solid-ts/package.json | 5 +- examples/solid-ts/src/pages/range-slider.tsx | 10 +- examples/solid-ts/src/pages/slider.tsx | 16 +- examples/vue-ts/CHANGELOG.md | 2 +- examples/vue-ts/package.json | 5 +- examples/vue-ts/src/pages/range-slider.tsx | 6 +- examples/vue-ts/src/pages/slider.tsx | 9 +- packages/machines/range-slider/CHANGELOG.md | 1067 ----------------- packages/machines/range-slider/README.md | 19 - packages/machines/range-slider/package.json | 53 - packages/machines/range-slider/src/index.ts | 4 - .../range-slider/src/range-slider.anatomy.ts | 14 - .../range-slider/src/range-slider.connect.ts | 313 ----- .../range-slider/src/range-slider.dom.ts | 47 - .../range-slider/src/range-slider.machine.ts | 306 ----- .../range-slider/src/range-slider.style.ts | 69 -- .../range-slider/src/range-slider.types.ts | 274 ----- .../range-slider/src/range-slider.utils.ts | 64 - packages/machines/range-slider/tsconfig.json | 7 - packages/machines/slider/CHANGELOG.md | 146 ++- packages/machines/slider/package.json | 7 +- packages/machines/slider/src/index.ts | 1 - .../machines/slider/src/slider.anatomy.ts | 1 + .../machines/slider/src/slider.connect.ts | 323 ++--- packages/machines/slider/src/slider.dom.ts | 43 +- .../machines/slider/src/slider.machine.ts | 216 ++-- packages/machines/slider/src/slider.style.ts | 115 +- packages/machines/slider/src/slider.types.ts | 181 +-- packages/machines/slider/src/slider.utils.ts | 63 +- pnpm-lock.yaml | 67 +- shared/src/controls.ts | 15 +- shared/src/style.css | 63 +- website/components/machines/range-slider.tsx | 6 +- website/components/machines/slider.tsx | 29 +- website/data/components/range-slider.mdx | 24 +- website/data/components/slider.mdx | 2 +- .../react/range-slider/installation.mdx | 4 +- .../snippets/react/range-slider/usage.mdx | 10 +- .../data/snippets/react/slider/tick-marks.mdx | 8 +- website/data/snippets/react/slider/usage.mdx | 12 +- .../solid/range-slider/installation.mdx | 4 +- .../snippets/solid/range-slider/usage.mdx | 10 +- .../data/snippets/solid/slider/tick-marks.mdx | 4 +- website/data/snippets/solid/slider/usage.mdx | 18 +- .../vue-jsx/range-slider/installation.mdx | 4 +- .../snippets/vue-jsx/range-slider/usage.mdx | 8 +- .../snippets/vue-jsx/slider/tick-marks.mdx | 4 +- .../data/snippets/vue-jsx/slider/usage.mdx | 12 +- .../vue-sfc/range-slider/installation.mdx | 4 +- .../snippets/vue-sfc/range-slider/usage.mdx | 10 +- .../snippets/vue-sfc/slider/tick-marks.mdx | 4 +- .../data/snippets/vue-sfc/slider/usage.mdx | 12 +- website/package.json | 3 +- 65 files changed, 934 insertions(+), 2917 deletions(-) create mode 100644 .changeset/slimy-ads-build.md delete mode 100644 packages/machines/range-slider/CHANGELOG.md delete mode 100644 packages/machines/range-slider/README.md delete mode 100644 packages/machines/range-slider/package.json delete mode 100644 packages/machines/range-slider/src/index.ts delete mode 100644 packages/machines/range-slider/src/range-slider.anatomy.ts delete mode 100644 packages/machines/range-slider/src/range-slider.connect.ts delete mode 100644 packages/machines/range-slider/src/range-slider.dom.ts delete mode 100644 packages/machines/range-slider/src/range-slider.machine.ts delete mode 100644 packages/machines/range-slider/src/range-slider.style.ts delete mode 100644 packages/machines/range-slider/src/range-slider.types.ts delete mode 100644 packages/machines/range-slider/src/range-slider.utils.ts delete mode 100644 packages/machines/range-slider/tsconfig.json diff --git a/.changeset/slimy-ads-build.md b/.changeset/slimy-ads-build.md new file mode 100644 index 0000000000..2ef0d63ba6 --- /dev/null +++ b/.changeset/slimy-ads-build.md @@ -0,0 +1,10 @@ +--- +"@zag-js/slider": minor +--- + +Merge the slider and range slider machines into one to prevent duplication. + +Some notable changes: + +- `value` and `onValueChange` type has been updated to be `number[]` +- Update `api.getThumbProps(index)` to `api.getThumbProps({ index })` diff --git a/.xstate/slider.js b/.xstate/slider.js index 8589aaf5da..9249ca3aca 100644 --- a/.xstate/slider.js +++ b/.xstate/slider.js @@ -13,24 +13,28 @@ const fetchMachine = createMachine({ id: "slider", initial: "idle", context: { + "hasIndex": false, "isHorizontal": false, "isHorizontal": false, "isVertical": false, "isVertical": false }, - activities: ["trackFormControlState", "trackThumbSize"], + entry: ["coarseValue"], + activities: ["trackFormControlState", "trackThumbsSize"], on: { - SET_VALUE: { + SET_VALUE: [{ + cond: "hasIndex", + actions: "setValueAtIndex" + }, { actions: "setValue" - }, + }], INCREMENT: { - actions: "increment" + actions: "incrementAtIndex" }, DECREMENT: { - actions: "decrement" + actions: "decrementAtIndex" } }, - entry: ["checkValue"], on: { UPDATE_CONTEXT: { actions: "updateContext" @@ -41,59 +45,65 @@ const fetchMachine = createMachine({ on: { POINTER_DOWN: { target: "dragging", - actions: ["setPointerValue", "invokeOnChangeStart", "focusThumb"] + actions: ["setClosestThumbIndex", "setPointerValue", "focusActiveThumb"] + }, + FOCUS: { + target: "focus", + actions: "setFocusedIndex" }, - FOCUS: "focus", THUMB_POINTER_DOWN: { target: "dragging", - actions: ["invokeOnChangeStart", "focusThumb"] + actions: ["setFocusedIndex", "focusActiveThumb"] } } }, focus: { - entry: "focusThumb", + entry: "focusActiveThumb", on: { POINTER_DOWN: { target: "dragging", - actions: ["setPointerValue", "invokeOnChangeStart", "focusThumb"] + actions: ["setClosestThumbIndex", "setPointerValue", "focusActiveThumb"] }, THUMB_POINTER_DOWN: { target: "dragging", - actions: ["invokeOnChangeStart", "focusThumb"] + actions: ["setFocusedIndex", "focusActiveThumb"] }, ARROW_LEFT: { cond: "isHorizontal", - actions: "decrement" + actions: "decrementAtIndex" }, ARROW_RIGHT: { cond: "isHorizontal", - actions: "increment" + actions: "incrementAtIndex" }, ARROW_UP: { cond: "isVertical", - actions: "increment" + actions: "incrementAtIndex" }, ARROW_DOWN: { cond: "isVertical", - actions: "decrement" + actions: "decrementAtIndex" }, PAGE_UP: { - actions: "increment" + actions: "incrementAtIndex" }, PAGE_DOWN: { - actions: "decrement" + actions: "decrementAtIndex" }, HOME: { - actions: "setToMin" + actions: "setActiveThumbToMin" }, END: { - actions: "setToMax" + actions: "setActiveThumbToMax" }, - BLUR: "idle" + BLUR: { + target: "idle", + actions: "clearFocusedIndex" + } } }, dragging: { - entry: "focusThumb", + entry: "focusActiveThumb", activities: "trackPointerMove", on: { POINTER_UP: { @@ -115,6 +125,7 @@ const fetchMachine = createMachine({ }) }, guards: { + "hasIndex": ctx => ctx["hasIndex"], "isHorizontal": ctx => ctx["isHorizontal"], "isVertical": ctx => ctx["isVertical"] } diff --git a/e2e/slider.e2e.ts b/e2e/slider.e2e.ts index fd5ec06a79..3b604b34b9 100644 --- a/e2e/slider.e2e.ts +++ b/e2e/slider.e2e.ts @@ -1,9 +1,9 @@ import { expect, test } from "@playwright/test" -import { testid, a11y, rect } from "./__utils" +import { part, a11y, rect } from "./__utils" -const output = testid("output") -const thumb = testid("thumb") -const track = testid("track") +const output = part("output") +const thumb = part("thumb") +const track = part("track") test.describe("slider", () => { test.beforeEach(async ({ page }) => { diff --git a/examples/next-ts/CHANGELOG.md b/examples/next-ts/CHANGELOG.md index afeff01eb5..38b9ec0c00 100644 --- a/examples/next-ts/CHANGELOG.md +++ b/examples/next-ts/CHANGELOG.md @@ -23,7 +23,7 @@ - @zag-js/number-input@0.1.13 - @zag-js/pin-input@0.1.11 - @zag-js/popover@0.1.11 - - @zag-js/range-slider@0.1.11 + - @zag-js/slider@0.1.11 - @zag-js/rating@0.1.11 - @zag-js/slider@0.1.11 - @zag-js/splitter@0.1.11 diff --git a/examples/next-ts/package.json b/examples/next-ts/package.json index 37a5151b4f..57b440f2c4 100644 --- a/examples/next-ts/package.json +++ b/examples/next-ts/package.json @@ -55,14 +55,13 @@ "@zag-js/presence": "workspace:*", "@zag-js/pressable": "workspace:*", "@zag-js/radio-group": "workspace:*", - "@zag-js/range-slider": "workspace:*", + "@zag-js/slider": "workspace:*", "@zag-js/rating-group": "workspace:*", "@zag-js/react": "workspace:*", "@zag-js/rect-utils": "workspace:*", "@zag-js/remove-scroll": "workspace:*", "@zag-js/select": "workspace:*", "@zag-js/shared": "workspace:*", - "@zag-js/slider": "workspace:*", "@zag-js/splitter": "workspace:*", "@zag-js/store": "workspace:*", "@zag-js/switch": "workspace:*", @@ -92,4 +91,4 @@ "typescript": "5.2.2" }, "license": "MIT" -} \ No newline at end of file +} diff --git a/examples/next-ts/pages/range-slider.tsx b/examples/next-ts/pages/range-slider.tsx index 4c4ea2cd76..5fc64be298 100644 --- a/examples/next-ts/pages/range-slider.tsx +++ b/examples/next-ts/pages/range-slider.tsx @@ -1,6 +1,6 @@ -import * as slider from "@zag-js/range-slider" +import * as slider from "@zag-js/slider" import { normalizeProps, useMachine } from "@zag-js/react" -import { rangeSliderControls } from "@zag-js/shared" +import { sliderControls } from "@zag-js/shared" import serialize from "form-serialize" import { useId } from "react" import { StateVisualizer } from "../components/state-visualizer" @@ -8,7 +8,7 @@ import { Toolbar } from "../components/toolbar" import { useControls } from "../hooks/use-controls" export default function Page() { - const controls = useControls(rangeSliderControls) + const controls = useControls(sliderControls) const [state, send] = useMachine( slider.machine({ @@ -42,8 +42,8 @@ export default function Page() {
{api.value.map((_, index) => ( -
- +
+
))}
diff --git a/examples/next-ts/pages/slider.tsx b/examples/next-ts/pages/slider.tsx index 895184331d..9b44d72c97 100644 --- a/examples/next-ts/pages/slider.tsx +++ b/examples/next-ts/pages/slider.tsx @@ -14,6 +14,7 @@ export default function Page() { slider.machine({ id: useId(), name: "quantity", + value: [0], }), { context: controls.context, @@ -46,9 +47,11 @@ export default function Page() {
-
- -
+ {api.value.map((_, index) => ( +
+ +
+ ))}
* diff --git a/examples/nuxt-ts/package.json b/examples/nuxt-ts/package.json index 4b3a8e2872..72616140b9 100644 --- a/examples/nuxt-ts/package.json +++ b/examples/nuxt-ts/package.json @@ -54,13 +54,12 @@ "@zag-js/presence": "workspace:*", "@zag-js/pressable": "workspace:*", "@zag-js/radio-group": "workspace:*", - "@zag-js/range-slider": "workspace:*", + "@zag-js/slider": "workspace:*", "@zag-js/rating-group": "workspace:*", "@zag-js/rect-utils": "workspace:*", "@zag-js/remove-scroll": "workspace:*", "@zag-js/select": "workspace:*", "@zag-js/shared": "workspace:*", - "@zag-js/slider": "workspace:*", "@zag-js/splitter": "workspace:*", "@zag-js/store": "workspace:*", "@zag-js/switch": "workspace:*", @@ -83,4 +82,4 @@ "@types/node": "^20.8.4", "nuxt": "^3.7.3" } -} \ No newline at end of file +} diff --git a/examples/nuxt-ts/pages/range-slider.vue b/examples/nuxt-ts/pages/range-slider.vue index 927ae4609c..59df52a217 100644 --- a/examples/nuxt-ts/pages/range-slider.vue +++ b/examples/nuxt-ts/pages/range-slider.vue @@ -1,10 +1,10 @@ @@ -24,9 +24,9 @@ const api = computed(() =>
- +
diff --git a/website/data/snippets/vue-sfc/slider/tick-marks.mdx b/website/data/snippets/vue-sfc/slider/tick-marks.mdx index 927f6f9b54..a68aa44c70 100644 --- a/website/data/snippets/vue-sfc/slider/tick-marks.mdx +++ b/website/data/snippets/vue-sfc/slider/tick-marks.mdx @@ -6,8 +6,8 @@
-
- +
+
diff --git a/website/data/snippets/vue-sfc/slider/usage.mdx b/website/data/snippets/vue-sfc/slider/usage.mdx index 7494b49504..4dbb03ebfe 100644 --- a/website/data/snippets/vue-sfc/slider/usage.mdx +++ b/website/data/snippets/vue-sfc/slider/usage.mdx @@ -4,7 +4,7 @@ import * as slider from "@zag-js/slider"; import { normalizeProps, useMachine } from "@zag-js/vue"; import { computed } from "vue"; -const [state, send] = useMachine(slider.machine({ id: "1" })); +const [state, send] = useMachine(slider.machine({ id: "1", value: [0] })); const api = computed(() => slider.connect(state.value, send, normalizeProps)); @@ -12,14 +12,18 @@ const api = computed(() => slider.connect(state.value, send, normalizeProps));
- {{ api.value }} + {{ api.value.at(0) }}
-
- +
+
diff --git a/website/package.json b/website/package.json index 10e252cbb1..bcf5fef2b2 100644 --- a/website/package.json +++ b/website/package.json @@ -41,11 +41,10 @@ "@zag-js/popover": "workspace:*", "@zag-js/pressable": "workspace:*", "@zag-js/radio-group": "workspace:*", - "@zag-js/range-slider": "workspace:*", + "@zag-js/slider": "workspace:*", "@zag-js/rating-group": "workspace:*", "@zag-js/react": "workspace:*", "@zag-js/select": "workspace:*", - "@zag-js/slider": "workspace:*", "@zag-js/splitter": "workspace:*", "@zag-js/switch": "workspace:*", "@zag-js/tabs": "workspace:*",