timepicker-ui-mcp 1.0.2 → 2.0.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.
@@ -0,0 +1,234 @@
1
+ [
2
+ {
3
+ "group": "Setup",
4
+ "symptom": "The picker opens but has no styles",
5
+ "fix": [
6
+ {
7
+ "text": "Import `timepicker-ui/main.css` once, for example in your app's entry file. It contains the core styles and the default `basic` theme."
8
+ },
9
+ {
10
+ "text": "For another theme, also import `timepicker-ui/theme-<name>.css` and set `ui.theme` to the same name.",
11
+ "code": {
12
+ "language": "typescript",
13
+ "source": "import { TimepickerUI } from 'timepicker-ui';\nimport 'timepicker-ui/main.css';\nimport 'timepicker-ui/theme-dark.css';\n\nconst picker = new TimepickerUI('#time', { ui: { theme: 'dark' } });\npicker.create();"
14
+ }
15
+ }
16
+ ],
17
+ "why": "The package ships its CSS as separate files, so you load only the themes you use. `timepicker-ui/index.css` contains the core styles and all 12 themes in one file.",
18
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#the-picker-opens-but-has-no-styles"
19
+ },
20
+ {
21
+ "group": "Setup",
22
+ "symptom": "Nothing happens when the input is clicked",
23
+ "fix": [
24
+ {
25
+ "text": "Call `create()` after `new TimepickerUI(...)`. The handlers that open the picker on click and on Enter are added by `create()`, not by the constructor.",
26
+ "code": {
27
+ "language": "typescript",
28
+ "source": "import { TimepickerUI } from 'timepicker-ui';\n\nconst picker = new TimepickerUI('#time');\npicker.create();"
29
+ }
30
+ },
31
+ {
32
+ "text": "If the console shows `Input element not found`, the selector matched nothing when the code ran, or the element has no `<input>` inside it. Run the code after the element is in the page."
33
+ }
34
+ ],
35
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#nothing-happens-when-the-input-is-clicked"
36
+ },
37
+ {
38
+ "group": "Setup",
39
+ "symptom": "A range, timezone or wheel option is ignored, or an error event fires",
40
+ "fix": [
41
+ {
42
+ "text": "Import the plugin from `timepicker-ui/plugins/<name>` and pass it to `PluginRegistry.register()` once, before the first `new TimepickerUI(...)`.",
43
+ "code": {
44
+ "language": "typescript",
45
+ "source": "import { TimepickerUI, PluginRegistry } from 'timepicker-ui';\nimport { RangePlugin } from 'timepicker-ui/plugins/range';\n\nPluginRegistry.register(RangePlugin);\n\nconst picker = new TimepickerUI('#time', { range: { enabled: true } });\npicker.create();"
46
+ }
47
+ },
48
+ {
49
+ "text": "A missing plugin is reported only through the `error` event, when the picker opens. Listen to it to see the message.",
50
+ "code": {
51
+ "language": "typescript",
52
+ "source": "picker.on('error', ({ error }) => console.warn(error));"
53
+ }
54
+ }
55
+ ],
56
+ "why": "Each picker sets up its plugins in its constructor, so a plugin registered after `new TimepickerUI(...)` does not work in that picker. Without its plugin, the picker leaves out the range and timezone controls and shows the clock instead of the wheel. With `range.enabled` set, OK then does not close the picker.",
57
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#a-range-timezone-or-wheel-option-is-ignored-or-an-error-event-fires"
58
+ },
59
+ {
60
+ "group": "Styling",
61
+ "symptom": "ui.theme: 'my-theme' has no effect",
62
+ "fix": [
63
+ {
64
+ "text": "Pass your class name in `ui.cssClass` instead. The picker adds the class to `.tp-ui-wrapper` when it opens.",
65
+ "code": {
66
+ "language": "typescript",
67
+ "source": "const picker = new TimepickerUI('#time', {\n ui: { cssClass: 'my-theme' },\n});\npicker.create();"
68
+ }
69
+ },
70
+ {
71
+ "text": "Set the `--tp-*` variables under `.tp-ui-wrapper.my-theme`. [CSS Variables](https://timepicker-ui.vercel.app/docs/api/css-variables) lists them.",
72
+ "code": {
73
+ "language": "css",
74
+ "source": ".tp-ui-wrapper.my-theme {\n --tp-bg: #ffffff;\n --tp-text: #1d1b20;\n --tp-primary: #0b57d0;\n --tp-on-primary: #ffffff;\n}"
75
+ }
76
+ }
77
+ ],
78
+ "why": "`ui.theme` selects one of the 12 built-in themes. The picker writes the name to the `data-theme` attribute of the modal and does not add it as a class, so a rule such as `.my-theme` never matches.",
79
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#uitheme-my-theme-has-no-effect"
80
+ },
81
+ {
82
+ "group": "Styling",
83
+ "symptom": "TypeScript rejects a custom ui.theme name",
84
+ "fix": [
85
+ {
86
+ "text": "Leave `ui.theme` unset or use a built-in name, and pass your own class in `ui.cssClass`. [The `ui.theme` entry above](https://timepicker-ui.vercel.app/docs/guides/troubleshooting#uitheme-my-theme-has-no-effect) shows the CSS."
87
+ }
88
+ ],
89
+ "why": "`ui.theme` is typed as a union of the 12 built-in theme names.",
90
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#typescript-rejects-a-custom-uitheme-name"
91
+ },
92
+ {
93
+ "group": "Styling",
94
+ "symptom": "The modal shows behind a header or inside a clipped container",
95
+ "fix": [
96
+ {
97
+ "text": "If you set `ui.appendTo`, point it at an element outside the clipped container, or remove the option so the modal goes to `<body>`."
98
+ },
99
+ {
100
+ "text": "The modal has `z-index: 5000`. If your header has a higher `z-index`, lower the header's value, or raise the modal's in CSS that loads after `timepicker-ui/main.css`.",
101
+ "code": {
102
+ "language": "css",
103
+ "source": ".tp-ui-modal {\n z-index: 10000;\n}"
104
+ }
105
+ }
106
+ ],
107
+ "why": "The modal is `position: fixed`. Inside an ancestor with `transform` or `filter`, a fixed element is placed relative to that ancestor instead of the viewport, and its `z-index` only counts inside it. `--tp-z-modal` is defined in `:root`, but no rule reads it, so changing it does nothing.",
108
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#the-modal-shows-behind-a-header-or-inside-a-clipped-container"
109
+ },
110
+ {
111
+ "group": "Styling",
112
+ "symptom": "My CSS does not override the built-in styles",
113
+ "fix": [
114
+ {
115
+ "text": "Give the picker a class with `ui.cssClass`, for example `'my-picker'`."
116
+ },
117
+ {
118
+ "text": "Start each selector with `.tp-ui-wrapper.my-picker`. Built-in state rules such as `.tp-ui-hour.active` and `.tp-ui-hour.mobile.active` use two or three classes, and the prefix adds two more.",
119
+ "code": {
120
+ "language": "css",
121
+ "source": ".tp-ui-wrapper.my-picker .tp-ui-hour.active,\n.tp-ui-wrapper.my-picker .tp-ui-minutes.active {\n background-color: #111111;\n color: #ffffff;\n}"
122
+ }
123
+ },
124
+ {
125
+ "text": "See [Specificity](https://timepicker-ui.vercel.app/docs/api/css-classes#specificity) on the CSS Classes page."
126
+ }
127
+ ],
128
+ "why": "A rule loses when it has fewer classes than the built-in one, or the same number and loads earlier.",
129
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#my-css-does-not-override-the-built-in-styles"
130
+ },
131
+ {
132
+ "group": "Frameworks",
133
+ "symptom": "ReferenceError: document is not defined or TimepickerUI requires browser environment in Next.js, Nuxt or SvelteKit",
134
+ "fix": [
135
+ {
136
+ "text": "Create the picker in a hook that runs only in the browser: `useEffect` in React, `onMounted` in Vue and Nuxt, `onMount` in Svelte and SvelteKit. In the Next.js App Router, the file also needs `'use client'`.",
137
+ "code": {
138
+ "language": "tsx",
139
+ "source": "'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { TimepickerUI } from 'timepicker-ui';\n\nexport function TimeField() {\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (!inputRef.current) return;\n const picker = new TimepickerUI(inputRef.current);\n picker.create();\n return () => picker.destroy();\n }, []);\n\n return <div className=\"tp-ui\"><input ref={inputRef} type=\"text\" /></div>;\n}"
140
+ }
141
+ },
142
+ {
143
+ "text": "Read `document` and `window` only inside that hook as well."
144
+ },
145
+ {
146
+ "text": "[Server Rendering](https://timepicker-ui.vercel.app/docs/guides/server-rendering) shows the setup for Next.js, Nuxt and SvelteKit."
147
+ }
148
+ ],
149
+ "why": "Importing `timepicker-ui` on the server is safe, because no module reads `window` or `document` when it loads. The constructor needs a browser: it throws `TimepickerUI requires browser environment` when `window` is undefined. `ReferenceError: document is not defined` comes from your own code, for example a `document.querySelector()` call in the component body.",
150
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#referenceerror-document-is-not-defined-nextjs-nuxt-sveltekit"
151
+ },
152
+ {
153
+ "group": "Frameworks",
154
+ "symptom": "Two pickers open, or events fire twice, in React development mode",
155
+ "fix": [
156
+ {
157
+ "text": "Return `() => picker.destroy()` from the effect that creates the picker.",
158
+ "code": {
159
+ "language": "tsx",
160
+ "source": "useEffect(() => {\n if (!inputRef.current) return;\n const picker = new TimepickerUI(inputRef.current);\n picker.create();\n return () => picker.destroy();\n}, []);"
161
+ }
162
+ }
163
+ ],
164
+ "why": "In development, Strict Mode runs each effect, then its cleanup, then the effect again. Without a cleanup, the first picker stays on the input next to the second one, and both open on click. `destroy()` removes the picker's listeners and its modal.",
165
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#two-pickers-open-or-events-fire-twice-in-react-development-mode"
166
+ },
167
+ {
168
+ "group": "Frameworks",
169
+ "symptom": "Failed to execute 'removeChild' on 'Node' when a React component unmounts",
170
+ "fix": [
171
+ {
172
+ "text": "Wrap the input in an element with the `tp-ui` class. The picker then uses that element as its root and leaves the input where React rendered it.",
173
+ "code": {
174
+ "language": "tsx",
175
+ "source": "return (\n <div className=\"tp-ui\">\n <input ref={inputRef} type=\"text\" />\n </div>\n);"
176
+ }
177
+ }
178
+ ],
179
+ "why": "Given a bare `<input>`, the constructor moves it into a new `div.tp-ui`, and `destroy()` does not remove that div. React still expects the input in its original parent, so removing it can fail. `timepicker-ui-react` renders the wrapper for you.",
180
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#failed-to-execute-removechild-on-node-when-a-react-component-unmounts"
181
+ },
182
+ {
183
+ "group": "Frameworks",
184
+ "symptom": "The input value does not update React state",
185
+ "fix": [
186
+ {
187
+ "text": "Set state in `callbacks.onConfirm`. It runs when the user confirms a time, after the picker has written it to the input.",
188
+ "code": {
189
+ "language": "tsx",
190
+ "source": "const [time, setTime] = useState('');\n\nuseEffect(() => {\n const input = inputRef.current;\n if (!input) return;\n const picker = new TimepickerUI(input, {\n callbacks: { onConfirm: () => setTime(input.value) },\n });\n picker.create();\n return () => picker.destroy();\n}, []);"
191
+ }
192
+ },
193
+ {
194
+ "text": "With `timepicker-ui-react`, pass `value` and update it in `onConfirm`.",
195
+ "code": {
196
+ "language": "tsx",
197
+ "source": "import { useState } from 'react';\nimport { Timepicker } from 'timepicker-ui-react';\n\nexport function TimeField() {\n const [time, setTime] = useState('10:00 AM');\n\n return (\n <Timepicker\n value={time}\n onConfirm={({ hour, minutes, type }) => setTime(`${hour}:${minutes} ${type}`)}\n />\n );\n}"
198
+ }
199
+ }
200
+ ],
201
+ "why": "The picker sets `input.value` directly and does not dispatch `input` or `change` events, so React's `onChange` never runs.",
202
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#the-input-value-does-not-update-react-state"
203
+ },
204
+ {
205
+ "group": "Frameworks",
206
+ "symptom": "Listeners or a modal stay after a route change",
207
+ "fix": [
208
+ {
209
+ "text": "Call `picker.destroy()` in your framework's cleanup hook: the function returned from `useEffect` in React, `onBeforeUnmount` in Vue, `ngOnDestroy` in Angular, or the function returned from `onMount` in Svelte.",
210
+ "code": {
211
+ "language": "vue",
212
+ "source": "<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref } from 'vue';\nimport { TimepickerUI } from 'timepicker-ui';\n\nconst input = ref<HTMLInputElement | null>(null);\nlet picker: TimepickerUI | undefined;\n\nonMounted(() => {\n picker = new TimepickerUI(input.value!);\n picker.create();\n});\n\nonBeforeUnmount(() => picker?.destroy());\n</script>\n\n<template>\n <div class=\"tp-ui\"><input ref=\"input\" type=\"text\" /></div>\n</template>"
213
+ }
214
+ }
215
+ ],
216
+ "why": "An open modal sits in `<body>`, or in the `ui.appendTo` element, outside your component. If the route changes while the picker is open, the modal stays, and by default the page scroll stays locked. `destroy()` removes the modal, the picker's listeners and the scroll lock.",
217
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#listeners-or-a-modal-stay-after-a-route-change"
218
+ },
219
+ {
220
+ "group": "Plugins",
221
+ "symptom": "ui.mode: 'wheel' or 'compact-wheel' still shows a clock",
222
+ "fix": [
223
+ {
224
+ "text": "Import `WheelPlugin` from `timepicker-ui/plugins/wheel` and register it once, before creating the picker.",
225
+ "code": {
226
+ "language": "typescript",
227
+ "source": "import { TimepickerUI, PluginRegistry } from 'timepicker-ui';\nimport { WheelPlugin } from 'timepicker-ui/plugins/wheel';\n\nPluginRegistry.register(WheelPlugin);\n\nconst picker = new TimepickerUI('#time', { ui: { mode: 'wheel' } });\npicker.create();"
228
+ }
229
+ }
230
+ ],
231
+ "why": "Without the plugin, the picker falls back to the clock face and emits `error` with the message `WheelPlugin is not registered. Import and register it: PluginRegistry.register(WheelPlugin)`.",
232
+ "docs": "https://timepicker-ui.vercel.app/docs/guides/troubleshooting#uimode-wheel-or-compact-wheel-still-shows-a-clock"
233
+ }
234
+ ]
@@ -10,9 +10,17 @@ function load(name, fallback) {
10
10
  return fallback;
11
11
  }
12
12
  }
13
+ export const META = load('meta.json', {
14
+ library: '4.5.0',
15
+ cssReference: null,
16
+ siteUrl: 'https://timepicker-ui.vercel.app',
17
+ });
13
18
  export const OPTION_GROUPS = load('options.json', {});
14
19
  export const EVENTS = load('events.json', []);
15
20
  export const CSS_VARS = load('css-variables.json', []);
16
21
  export const THEME_VARS = load('themes.json', {});
17
- export const CSS_CLASSES = load('css-classes.json', []);
22
+ export const CSS_CLASSES = load('css-classes.json', { classes: [], modifiers: [] });
23
+ export const TROUBLESHOOTING = load('troubleshooting.json', []);
24
+ export const MIGRATION_V5 = load('migration-v5.json', { renamed: [], removed: [] });
18
25
  export const OPTION_GROUP_NAMES = Object.keys(OPTION_GROUPS);
26
+ export const CSS_VAR_GROUPS = [...new Set(CSS_VARS.map((v) => v.group))];