Skip to content

Commit

Permalink
refactor: timer machine
Browse files Browse the repository at this point in the history
  • Loading branch information
segunadebayo committed Sep 12, 2024
1 parent 7db581b commit f079c60
Show file tree
Hide file tree
Showing 23 changed files with 328 additions and 172 deletions.
51 changes: 51 additions & 0 deletions .changeset/hip-pots-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
"@zag-js/timer": minor
---

- Introduces new area and control parts for better anatomy and structure.
- [BREAKING] Move `role"timer` to new area part.
- Automatically hide the action triggers based on the action prop passed.

**BEFORE:**

```tsx
<div>
<div {...api.getRootProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>
<div>
<button {...api.getActionTriggerProps({ action: "start" })}>START</button>
<button {...api.getActionTriggerProps({ action: "pause" })}>PAUSE</button>
<button {...api.getActionTriggerProps({ action: "resume" })}>RESUME</button>
<button {...api.getActionTriggerProps({ action: "reset" })}>RESET</button>
</div>
</div>
```

**AFTER:**

```tsx
<div {...api.getRootProps()}>
<div {...api.getAreaProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>
<div {...api.getControlProps()}>
<button {...api.getActionTriggerProps({ action: "start" })}>START</button>
<button {...api.getActionTriggerProps({ action: "pause" })}>PAUSE</button>
<button {...api.getActionTriggerProps({ action: "resume" })}>RESUME</button>
<button {...api.getActionTriggerProps({ action: "reset" })}>RESET</button>
</div>
</div>
```
26 changes: 14 additions & 12 deletions examples/next-ts/pages/timer-countdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@ export default function Page() {
<>
<main className="timer">
<div {...api.getRootProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
<div {...api.getAreaProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>
</div>

<div style={{ display: "flex", gap: "4px" }}>
<button onClick={api.start}>START</button>
<button onClick={api.pause}>PAUSE</button>
<button onClick={api.resume}>RESUME</button>
<button onClick={api.reset}>RESET</button>
<div {...api.getControlProps()}>
<button {...api.getActionTriggerProps({ action: "start" })}>START</button>
<button {...api.getActionTriggerProps({ action: "pause" })}>PAUSE</button>
<button {...api.getActionTriggerProps({ action: "resume" })}>RESUME</button>
<button {...api.getActionTriggerProps({ action: "reset" })}>RESET</button>
</div>
</main>

Expand Down
28 changes: 15 additions & 13 deletions examples/next-ts/pages/timer-stopwatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@ export default function Page() {
<>
<main className="timer">
<div {...api.getRootProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>
<div {...api.getAreaProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>

<div style={{ display: "flex", gap: "4px" }}>
<button onClick={api.start}>START</button>
<button onClick={api.pause}>PAUSE</button>
<button onClick={api.resume}>RESUME</button>
<button onClick={api.reset}>RESET</button>
<div {...api.getControlProps()}>
<button {...api.getActionTriggerProps({ action: "start" })}>START</button>
<button {...api.getActionTriggerProps({ action: "pause" })}>PAUSE</button>
<button {...api.getActionTriggerProps({ action: "resume" })}>RESUME</button>
<button {...api.getActionTriggerProps({ action: "reset" })}>RESET</button>
</div>
</div>
</main>

Expand Down
28 changes: 15 additions & 13 deletions examples/nuxt-ts/pages/timer-countdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,21 @@ const api = computed(() => timer.connect(state.value, send, normalizeProps))
<template>
<main class="timer">
<div v-bind="api.getRootProps()">
<div v-bind="api.getItemProps({ type: 'days' })">{{ api.formattedTime.days }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'hours' })">{{ api.formattedTime.hours }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'minutes' })">{{ api.formattedTime.minutes }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'seconds' })">{{ api.formattedTime.seconds }}</div>
</div>
<div style="display: flex; gap: 4px">
<button @click="api.start">START</button>
<button @click="api.pause">PAUSE</button>
<button @click="api.resume">RESUME</button>
<button @click="api.reset">RESET</button>
<div v-bind="api.getAreaProps()">
<div v-bind="api.getItemProps({ type: 'days' })">{{ api.formattedTime.days }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'hours' })">{{ api.formattedTime.hours }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'minutes' })">{{ api.formattedTime.minutes }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'seconds' })">{{ api.formattedTime.seconds }}</div>
</div>
<div v-bind="api.getControlProps()">
<button v-bind="api.getActionTriggerProps({ action: 'start' })">START</button>
<button v-bind="api.getActionTriggerProps({ action: 'pause' })">PAUSE</button>
<button v-bind="api.getActionTriggerProps({ action: 'resume' })">RESUME</button>
<button v-bind="api.getActionTriggerProps({ action: 'reset' })">RESET</button>
</div>
</div>
</main>

Expand Down
28 changes: 15 additions & 13 deletions examples/nuxt-ts/pages/timer-stopwatch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@ const api = computed(() => timer.connect(state.value, send, normalizeProps))
<template>
<main class="timer">
<div v-bind="api.getRootProps()">
<div v-bind="api.getItemProps({ type: 'days' })">{{ api.formattedTime.days }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'hours' })">{{ api.formattedTime.hours }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'minutes' })">{{ api.formattedTime.minutes }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'seconds' })">{{ api.formattedTime.seconds }}</div>
</div>
<div style="display: flex; gap: 4px">
<button @click="api.start">START</button>
<button @click="api.pause">PAUSE</button>
<button @click="api.resume">RESUME</button>
<button @click="api.reset">RESET</button>
<div v-bind="api.getAreaProps()">
<div v-bind="api.getItemProps({ type: 'days' })">{{ api.formattedTime.days }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'hours' })">{{ api.formattedTime.hours }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'minutes' })">{{ api.formattedTime.minutes }}</div>
<div v-bind="api.getSeparatorProps()">:</div>
<div v-bind="api.getItemProps({ type: 'seconds' })">{{ api.formattedTime.seconds }}</div>
</div>
<div v-bind="api.getControlProps()">
<button v-bind="api.getActionTriggerProps({ action: 'start' })">START</button>
<button v-bind="api.getActionTriggerProps({ action: 'pause' })">PAUSE</button>
<button v-bind="api.getActionTriggerProps({ action: 'resume' })">RESUME</button>
<button v-bind="api.getActionTriggerProps({ action: 'reset' })">RESET</button>
</div>
</div>
</main>

Expand Down
4 changes: 2 additions & 2 deletions examples/solid-ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@
"form-serialize": "0.7.2",
"lucide-solid": "0.428.0",
"match-sorter": "6.3.4",
"solid-js": "1.8.21",
"solid-js": "1.8.22",
"vinxi": "0.4.1"
},
"engines": {
"node": ">=18"
}
}
}
18 changes: 10 additions & 8 deletions examples/solid-ts/src/routes/timer-countdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ export default function Page() {
<>
<main class="timer">
<div {...api().getRootProps()}>
<div {...api().getItemProps({ type: "days" })}>{api().formattedTime.days}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "hours" })}>{api().formattedTime.hours}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "minutes" })}>{api().formattedTime.minutes}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "seconds" })}>{api().formattedTime.seconds}</div>
<div {...api().getAreaProps()}>
<div {...api().getItemProps({ type: "days" })}>{api().formattedTime.days}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "hours" })}>{api().formattedTime.hours}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "minutes" })}>{api().formattedTime.minutes}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "seconds" })}>{api().formattedTime.seconds}</div>
</div>
</div>

<div style={{ display: "flex", gap: "4px" }}>
<div {...api().getControlProps()}>
<button onClick={api().start}>START</button>
<button onClick={api().pause}>PAUSE</button>
<button onClick={api().resume}>RESUME</button>
Expand Down
18 changes: 10 additions & 8 deletions examples/solid-ts/src/routes/timer-stopwatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@ export default function Page() {
<>
<main class="timer">
<div {...api().getRootProps()}>
<div {...api().getItemProps({ type: "days" })}>{api().formattedTime.days}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "hours" })}>{api().formattedTime.hours}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "minutes" })}>{api().formattedTime.minutes}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "seconds" })}>{api().formattedTime.seconds}</div>
<div {...api().getAreaProps()}>
<div {...api().getItemProps({ type: "days" })}>{api().formattedTime.days}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "hours" })}>{api().formattedTime.hours}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "minutes" })}>{api().formattedTime.minutes}</div>
<div {...api().getSeparatorProps()}>:</div>
<div {...api().getItemProps({ type: "seconds" })}>{api().formattedTime.seconds}</div>
</div>
</div>

<div style={{ display: "flex", gap: "4px" }}>
<div {...api().getControlProps()}>
<button onClick={api().start}>START</button>
<button onClick={api().pause}>PAUSE</button>
<button onClick={api().resume}>RESUME</button>
Expand Down
28 changes: 15 additions & 13 deletions examples/svelte-ts/src/routes/timer-countdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,22 @@

<main class="timer">
<div {...api.getRootProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>
<div {...api.getAreaProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>

<div style="display:flex; gap: 4px">
<button onclick={api.start}>START</button>
<button onclick={api.pause}>PAUSE</button>
<button onclick={api.resume}>RESUME</button>
<button onclick={api.reset}>RESET</button>
<div {...api.getControlProps()}>
<button {...api.getActionTriggerProps({ action: "start" })}>START</button>
<button {...api.getActionTriggerProps({ action: "pause" })}>PAUSE</button>
<button {...api.getActionTriggerProps({ action: "resume" })}>RESUME</button>
<button {...api.getActionTriggerProps({ action: "reset" })}>RESET</button>
</div>
</div>
</main>

Expand Down
28 changes: 15 additions & 13 deletions examples/svelte-ts/src/routes/timer-stopwatch.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,22 @@

<main class="timer">
<div {...api.getRootProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>
<div {...api.getAreaProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>

<div style="display:flex; gap: 4px">
<button onclick={api.start}>START</button>
<button onclick={api.pause}>PAUSE</button>
<button onclick={api.resume}>RESUME</button>
<button onclick={api.reset}>RESET</button>
<div {...api.getControlProps()}>
<button {...api.getActionTriggerProps({ action: "start" })}>START</button>
<button {...api.getActionTriggerProps({ action: "pause" })}>PAUSE</button>
<button {...api.getActionTriggerProps({ action: "resume" })}>RESUME</button>
<button {...api.getActionTriggerProps({ action: "reset" })}>RESET</button>
</div>
</div>
</main>

Expand Down
3 changes: 2 additions & 1 deletion packages/machines/timer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
},
"dependencies": {
"@zag-js/anatomy": "workspace:*",
"@zag-js/dom-query": "workspace:*",
"@zag-js/core": "workspace:*",
"@zag-js/types": "workspace:*",
"@zag-js/utils": "workspace:*"
Expand All @@ -46,4 +47,4 @@
},
"clean-package": "../../../clean-package.config.json",
"main": "src/index.ts"
}
}
1 change: 1 addition & 0 deletions packages/machines/timer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type {
MachineApi as Api,
UserDefinedContext as Context,
ItemProps,
ElementIds,
MachineState,
Service,
TickDetails,
Expand Down
2 changes: 2 additions & 0 deletions packages/machines/timer/src/timer.anatomy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { createAnatomy } from "@zag-js/anatomy"

export const anatomy = createAnatomy("timer").parts(
"root",
"area",
"control",
"item",
"itemValue",
"itemLabel",
Expand Down
Loading

0 comments on commit f079c60

Please sign in to comment.