@reni-corp/reni-2c-ui 0.4.8 → 0.4.10

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.
Files changed (31) hide show
  1. package/dist/components/elements/Button.vue.d.ts.map +1 -1
  2. package/dist/components/elements/Pagination.vue.d.ts +20 -0
  3. package/dist/components/elements/Pagination.vue.d.ts.map +1 -0
  4. package/dist/components/features/VariationSelector.vue.d.ts +38 -0
  5. package/dist/components/features/VariationSelector.vue.d.ts.map +1 -0
  6. package/dist/components/interactive/Tabs.vue.d.ts.map +1 -1
  7. package/dist/components/navigation/Drawer.vue.d.ts +3 -0
  8. package/dist/components/navigation/Drawer.vue.d.ts.map +1 -1
  9. package/dist/components/renderless/ItemFilter.vue.d.ts +49 -0
  10. package/dist/components/renderless/ItemFilter.vue.d.ts.map +1 -0
  11. package/dist/composable/usePagination.d.ts +31 -0
  12. package/dist/composable/usePagination.d.ts.map +1 -0
  13. package/dist/index.d.ts +7 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.es.js +4638 -4369
  16. package/dist/mockServiceWorker.js +349 -0
  17. package/dist/mocks/handlers/index.d.ts +2 -0
  18. package/dist/mocks/handlers/index.d.ts.map +1 -0
  19. package/dist/mocks/handlers/products.d.ts +2 -0
  20. package/dist/mocks/handlers/products.d.ts.map +1 -0
  21. package/dist/script.es.js +5904 -5635
  22. package/dist/script.umd.js +28 -28
  23. package/dist/style.css +1 -1
  24. package/dist/utils.d.ts.map +1 -1
  25. package/package.json +8 -1
  26. package/src/stories/DataProvider.stories.ts +182 -0
  27. package/src/stories/ItemFilter.stories.ts +283 -0
  28. package/src/stories/Pagination.stories.ts +133 -0
  29. package/src/stories/VariationSelector.stories.ts +241 -0
  30. package/dist/components/renderless/OptionGroupSwitchController.vue.d.ts +0 -41
  31. package/dist/components/renderless/OptionGroupSwitchController.vue.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reni-corp/reni-2c-ui",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "type": "module",
5
5
  "main": "./dist/script.umd.js",
6
6
  "module": "./dist/index.es.js",
@@ -107,6 +107,8 @@
107
107
  "eslint-plugin-vue": "^9.29.0",
108
108
  "globals": "^15.12.0",
109
109
  "happy-dom": "^20.0.0",
110
+ "msw": "^2.12.10",
111
+ "msw-storybook-addon": "^2.0.6",
110
112
  "plop": "^3.1.2",
111
113
  "postcss": "^8.5.3",
112
114
  "postcss-html": "^1.8.0",
@@ -130,5 +132,10 @@
130
132
  "vitest": "^4.0.18",
131
133
  "vue-eslint-parser": "^10.2.0",
132
134
  "vue-tsc": "^1.8.5"
135
+ },
136
+ "msw": {
137
+ "workerDirectory": [
138
+ "public"
139
+ ]
133
140
  }
134
141
  }
@@ -0,0 +1,182 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
+ import DataProvider from '@/components/renderless/DataProvider.vue'
3
+ import ProductList from '@/components/features/ProductList.vue'
4
+ import Tabs from '@/components/interactive/Tabs.vue'
5
+ import Tab from '@/components/interactive/Tab.vue'
6
+ import Button from '@/components/elements/Button.vue'
7
+ import Stack from '@/components/layouts/Stack.vue'
8
+ import Text from '@/components/elements/Text.vue'
9
+ import Spinner from '@/components/elements/Spinner.vue'
10
+ import Divider from '@/components/elements/Divider.vue'
11
+ import { ref, computed } from 'vue'
12
+
13
+ const meta: Meta<typeof DataProvider> = {
14
+ title: 'Renderless/DataProvider',
15
+ component: DataProvider,
16
+ tags: ['autodocs'],
17
+ }
18
+
19
+ export default meta
20
+ type Story = StoryObj<typeof DataProvider>
21
+
22
+ const storyComponents = {
23
+ 'rn-data-provider': DataProvider,
24
+ 'rn-product-list': ProductList,
25
+ 'rn-tabs': Tabs,
26
+ 'rn-tab': Tab,
27
+ 'rn-button': Button,
28
+ 'rn-stack': Stack,
29
+ 'rn-text': Text,
30
+ 'rn-spinner': Spinner,
31
+ 'rn-divider': Divider,
32
+ }
33
+
34
+ export const 基本: Story = {
35
+ render: () => ({
36
+ components: storyComponents,
37
+ template: `
38
+ <div class="sb-canvas" style="padding: 20px;">
39
+ <rn-data-provider url="/api/products" :limit="8" v-slot="{ data, loading, error }">
40
+ <rn-stack direction="vertical" horizontal-re-size="fill" gap="md">
41
+ <rn-stack v-if="loading" horizontal-re-size="fill" horizontal-align="center" vertical-align="center" style="min-height: 200px;">
42
+ <rn-spinner size="md" />
43
+ </rn-stack>
44
+ <rn-text v-else-if="error" color="danger">{{ error.message }}</rn-text>
45
+ <rn-product-list v-else :data="data" :pc-columns="4" :sp-columns="2" />
46
+ </rn-stack>
47
+ </rn-data-provider>
48
+ </div>
49
+ `,
50
+ }),
51
+ }
52
+
53
+ export const ページネーション: Story = {
54
+ render: () => ({
55
+ components: storyComponents,
56
+ template: `
57
+ <div class="sb-canvas" style="padding: 20px;">
58
+ <rn-data-provider
59
+ url="/api/products"
60
+ :limit="8"
61
+ :pagination="true"
62
+ v-slot="{ data, loading, currentPage, next, prev }"
63
+ >
64
+ <rn-stack direction="vertical" horizontal-re-size="fill" gap="lg">
65
+ <rn-stack v-if="loading" horizontal-re-size="fill" horizontal-align="center" vertical-align="center" style="min-height: 200px;">
66
+ <rn-spinner size="md" />
67
+ </rn-stack>
68
+ <template v-else>
69
+ <rn-product-list :data="data" :pc-columns="4" :sp-columns="2" />
70
+ <rn-stack direction="horizontal" horizontal-re-size="fill" horizontal-align="center" vertical-align="center" gap="md">
71
+ <rn-button variant="outlined" size="sm" :disabled="currentPage <= 1" @click="prev">前へ</rn-button>
72
+ <rn-text size="body" weight="bold">{{ currentPage }}</rn-text>
73
+ <rn-button variant="outlined" size="sm" :disabled="data.length === 0" @click="next">次へ</rn-button>
74
+ </rn-stack>
75
+ </template>
76
+ </rn-stack>
77
+ </rn-data-provider>
78
+ </div>
79
+ `,
80
+ }),
81
+ }
82
+
83
+ export const 無限スクロール風: Story = {
84
+ render: () => ({
85
+ components: storyComponents,
86
+ template: `
87
+ <div class="sb-canvas" style="padding: 20px;">
88
+ <rn-data-provider
89
+ url="/api/products"
90
+ :limit="8"
91
+ :pagination="true"
92
+ :accumulate="true"
93
+ v-slot="{ data, loading, moreLoading, next }"
94
+ >
95
+ <rn-stack direction="vertical" horizontal-re-size="fill" gap="lg">
96
+ <rn-stack v-if="loading" horizontal-re-size="fill" horizontal-align="center" vertical-align="center" style="min-height: 200px;">
97
+ <rn-spinner size="md" />
98
+ </rn-stack>
99
+ <rn-product-list
100
+ v-else
101
+ :data="data"
102
+ :pc-columns="4"
103
+ :sp-columns="2"
104
+ :infinite-scroll="true"
105
+ :has-more="data.length % 8 === 0"
106
+ :loading-more="moreLoading"
107
+ @load-more="next"
108
+ />
109
+ </rn-stack>
110
+ </rn-data-provider>
111
+ </div>
112
+ `,
113
+ }),
114
+ }
115
+
116
+ export const タグ絞り込み_LoadMore: Story = {
117
+ render: () => ({
118
+ components: storyComponents,
119
+ setup() {
120
+ const tabIndex = ref(0)
121
+ const activeTagCode = ref<string | null>(null)
122
+ const productQuery = computed(() =>
123
+ activeTagCode.value ? `tag_codes=${activeTagCode.value}` : '',
124
+ )
125
+ const selectTag = (code: string | null, index: number) => {
126
+ activeTagCode.value = code
127
+ tabIndex.value = index
128
+ }
129
+ return { tabIndex, activeTagCode, productQuery, selectTag }
130
+ },
131
+ template: `
132
+ <div class="sb-canvas" style="padding: 20px;">
133
+ <rn-data-provider url="/api/tags" v-slot="{ data: tags, loading: tagsLoading }">
134
+ <rn-stack v-if="tagsLoading" horizontal-re-size="fill" horizontal-align="center" vertical-align="center" style="min-height: 200px;">
135
+ <rn-spinner size="md" />
136
+ </rn-stack>
137
+ <rn-stack v-else direction="vertical" horizontal-re-size="fill" gap="md">
138
+ <div>
139
+ <rn-tabs :modelValue="tabIndex" :is-scrollable="true">
140
+ <rn-tab
141
+ label="すべて"
142
+ :active="!activeTagCode"
143
+ @click="selectTag(null, 0)"
144
+ />
145
+ <rn-tab
146
+ v-for="(tag, i) in tags"
147
+ :key="tag.code"
148
+ :label="tag.name"
149
+ :active="activeTagCode === tag.code"
150
+ @click="selectTag(tag.code, i + 1)"
151
+ />
152
+ </rn-tabs>
153
+ <rn-divider />
154
+ </div>
155
+ <rn-data-provider
156
+ url="/api/products"
157
+ :query="productQuery"
158
+ :limit="8"
159
+ :pagination="true"
160
+ :accumulate="true"
161
+ v-slot="{ data: products, loading, moreLoading, next }"
162
+ >
163
+ <rn-stack v-if="loading" horizontal-re-size="fill" horizontal-align="center" vertical-align="center" style="min-height: 200px;">
164
+ <rn-spinner size="md" />
165
+ </rn-stack>
166
+ <rn-product-list
167
+ v-else
168
+ :data="products"
169
+ :pc-columns="4"
170
+ :sp-columns="2"
171
+ :infinite-scroll="true"
172
+ :has-more="products.length % 8 === 0"
173
+ :loading-more="moreLoading"
174
+ @load-more="next"
175
+ />
176
+ </rn-data-provider>
177
+ </rn-stack>
178
+ </rn-data-provider>
179
+ </div>
180
+ `,
181
+ }),
182
+ }
@@ -0,0 +1,283 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
+ import ItemFilter, {
3
+ type ItemFilterProps,
4
+ } from '@/components/renderless/ItemFilter.vue'
5
+ import DataProvider from '@/components/renderless/DataProvider.vue'
6
+ import ProductList from '@/components/features/ProductList.vue'
7
+ import Tabs from '@/components/interactive/Tabs.vue'
8
+ import Tab from '@/components/interactive/Tab.vue'
9
+ import Stack from '@/components/layouts/Stack.vue'
10
+ import Spinner from '@/components/elements/Spinner.vue'
11
+ import Divider from '@/components/elements/Divider.vue'
12
+ import { ref } from 'vue'
13
+
14
+ const meta: Meta<typeof ItemFilter> = {
15
+ title: 'Renderless/ItemFilter',
16
+ component: ItemFilter,
17
+ tags: ['autodocs'],
18
+ }
19
+
20
+ export default meta
21
+ type StoryArgs = ItemFilterProps
22
+ type Story = StoryObj<StoryArgs>
23
+
24
+ // --- タグデータ(実API構造準拠) ---
25
+ const mockTags = [
26
+ { id: '2649', name: 'Tshirt / Long Sleeve Tshirt', code: 'OMT-T-001' },
27
+ { id: '2650', name: 'Bag', code: 'OMT-T-002' },
28
+ { id: '2651', name: 'Other', code: 'OMT-T-003' },
29
+ { id: '2652', name: 'CD / Cassette / 7inch', code: 'OMT-T-004' },
30
+ { id: '3266', name: 'Live at 日本武道館', code: 'OMT-T-011' },
31
+ { id: '3082', name: 'ONE MAN TOUR 2012-2025 Shinka', code: 'OMT-T-010' },
32
+ ]
33
+
34
+ // --- 商品データ(タグ多対多) ---
35
+ const tagAssignments = [
36
+ [{ id: '2649', text: 'Tshirt / Long Sleeve Tshirt' }],
37
+ [
38
+ { id: '2649', text: 'Tshirt / Long Sleeve Tshirt' },
39
+ { id: '3266', text: 'Live at 日本武道館' },
40
+ ],
41
+ [{ id: '2650', text: 'Bag' }],
42
+ [{ id: '2652', text: 'CD / Cassette / 7inch' }],
43
+ [
44
+ { id: '2651', text: 'Other' },
45
+ { id: '3082', text: 'ONE MAN TOUR 2012-2025 Shinka' },
46
+ ],
47
+ [{ id: '3266', text: 'Live at 日本武道館' }],
48
+ [
49
+ { id: '2650', text: 'Bag' },
50
+ { id: '3266', text: 'Live at 日本武道館' },
51
+ ],
52
+ [{ id: '3082', text: 'ONE MAN TOUR 2012-2025 Shinka' }],
53
+ ]
54
+
55
+ const productNames = [
56
+ 'ロゴ Tシャツ',
57
+ '武道館限定 ロングスリーブ',
58
+ 'キャンバストートバッグ',
59
+ '1st Album「Ammolite」',
60
+ 'Shinka ツアータオル',
61
+ '武道館公演 パンフレット',
62
+ '武道館限定 サコッシュ',
63
+ 'Shinka ラバーバンド',
64
+ 'フォトTシャツ BLACK',
65
+ 'フォトTシャツ WHITE',
66
+ '2nd EP「Pieces」',
67
+ 'アクリルキーホルダー',
68
+ ]
69
+
70
+ const generateMockProducts = (count: number) => {
71
+ const products = []
72
+ for (let i = 1; i <= count; i++) {
73
+ products.push({
74
+ product_id: `product_${i}`,
75
+ product_code: `OMT-${String(i).padStart(3, '0')}`,
76
+ title: productNames[(i - 1) % productNames.length],
77
+ title2: '',
78
+ price_sale: [2200, 3300, 4400, 5500, 6600, 1650, 3850, 1100][i % 8],
79
+ price_prefix_freeWord: '',
80
+ slide: 1,
81
+ product_url: `https://example.com/products/product_${i}`,
82
+ img_urls: [
83
+ `https://placehold.jp/400x400.png?text=Product${i}`,
84
+ `https://placehold.jp/400x400.png?text=Image${i}-2`,
85
+ ],
86
+ label_urls: [],
87
+ label_texts: tagAssignments[(i - 1) % tagAssignments.length],
88
+ soldout_url: '',
89
+ is_soldout: i % 7 === 0,
90
+ is_forced_publish: i % 11 === 0,
91
+ })
92
+ }
93
+ return products
94
+ }
95
+
96
+ const mockProducts = generateMockProducts(24)
97
+
98
+ // --- ストーリー共通コンポーネント ---
99
+ const storyComponents = {
100
+ 'rn-item-filter': ItemFilter,
101
+ 'rn-data-provider': DataProvider,
102
+ 'rn-product-list': ProductList,
103
+ 'rn-tabs': Tabs,
104
+ 'rn-tab': Tab,
105
+ 'rn-stack': Stack,
106
+ 'rn-spinner': Spinner,
107
+ 'rn-divider': Divider,
108
+ }
109
+
110
+ export const 基本: Story = {
111
+ render: () => ({
112
+ components: storyComponents,
113
+ setup() {
114
+ const current = ref(0)
115
+ const tags = mockTags
116
+ const products = mockProducts
117
+ return { current, tags, products }
118
+ },
119
+ template: `
120
+ <div class="sb-canvas" style="padding: 20px;">
121
+ <rn-item-filter
122
+ :groups="tags"
123
+ :items="products"
124
+ :item-groups="(p) => p.label_texts"
125
+ all-label="すべて"
126
+ >
127
+ <template #default="{ filteredItems, groups, setActive }">
128
+ <rn-tabs :modelValue="current" :is-scrollable="true">
129
+ <rn-tab
130
+ v-for="(g, index) in groups"
131
+ :key="g.key"
132
+ :label="g.label"
133
+ :active="g.isActive"
134
+ @click="current = index; setActive(g.key)"
135
+ />
136
+ </rn-tabs>
137
+ <rn-divider />
138
+ <rn-product-list :data="filteredItems" :pc-columns="4" :sp-columns="2" />
139
+ </template>
140
+ </rn-item-filter>
141
+ </div>
142
+ `,
143
+ }),
144
+ }
145
+
146
+ export const プレフィルタ付き: Story = {
147
+ render: () => ({
148
+ components: storyComponents,
149
+ setup() {
150
+ const current = ref(0)
151
+ const tags = mockTags
152
+ const products = mockProducts
153
+ const availableFilter = (p: any) => !p.is_soldout && !p.is_forced_publish
154
+ return { current, tags, products, availableFilter }
155
+ },
156
+ template: `
157
+ <div class="sb-canvas" style="padding: 20px;">
158
+ <rn-item-filter
159
+ :groups="tags"
160
+ :items="products"
161
+ :item-groups="(p) => p.label_texts"
162
+ :filter="availableFilter"
163
+ all-label="すべて"
164
+ >
165
+ <template #default="{ filteredItems, groups, setActive }">
166
+ <rn-tabs :modelValue="current" :is-scrollable="true">
167
+ <rn-tab
168
+ v-for="(g, index) in groups"
169
+ :key="g.key"
170
+ :label="g.label"
171
+ :active="g.isActive"
172
+ @click="current = index; setActive(g.key)"
173
+ />
174
+ </rn-tabs>
175
+ <rn-divider />
176
+ <rn-product-list :data="filteredItems" :pc-columns="4" :sp-columns="2" />
177
+ </template>
178
+ </rn-item-filter>
179
+ </div>
180
+ `,
181
+ }),
182
+ }
183
+
184
+ export const キー指定マッチ: Story = {
185
+ render: () => ({
186
+ components: storyComponents,
187
+ setup() {
188
+ const current = ref(0)
189
+ const categories = [
190
+ { code: 'apparel', name: 'アパレル' },
191
+ { code: 'goods', name: 'グッズ' },
192
+ { code: 'media', name: 'CD / メディア' },
193
+ ]
194
+ const products = Array.from({ length: 18 }, (_, i) => ({
195
+ product_id: `product_${i + 1}`,
196
+ product_code: `CAT-${String(i + 1).padStart(3, '0')}`,
197
+ title: productNames[i % productNames.length],
198
+ price_sale: [2200, 3300, 4400, 5500, 1650][i % 5],
199
+ price_prefix_freeWord: '',
200
+ slide: 1,
201
+ product_url: `https://example.com/products/product_${i + 1}`,
202
+ img_urls: [`https://placehold.jp/400x400.png?text=Product${i + 1}`],
203
+ label_urls: [],
204
+ label_texts: [],
205
+ soldout_url: '',
206
+ is_soldout: false,
207
+ is_forced_publish: false,
208
+ category: categories[i % categories.length].code,
209
+ }))
210
+ return { current, categories, products }
211
+ },
212
+ template: `
213
+ <div class="sb-canvas" style="padding: 20px;">
214
+ <rn-item-filter
215
+ :groups="categories"
216
+ :items="products"
217
+ item-groups="category"
218
+ group-key="code"
219
+ group-label="name"
220
+ all-label="すべて"
221
+ >
222
+ <template #default="{ filteredItems, groups, setActive }">
223
+ <rn-tabs :modelValue="current" :is-scrollable="true">
224
+ <rn-tab
225
+ v-for="(g, index) in groups"
226
+ :key="g.key"
227
+ :label="g.label"
228
+ :active="g.isActive"
229
+ @click="current = index; setActive(g.key)"
230
+ />
231
+ </rn-tabs>
232
+ <rn-divider />
233
+ <rn-product-list :data="filteredItems" :pc-columns="4" :sp-columns="2" />
234
+ </template>
235
+ </rn-item-filter>
236
+ </div>
237
+ `,
238
+ }),
239
+ }
240
+
241
+ export const API連携: Story = {
242
+ render: () => ({
243
+ components: storyComponents,
244
+ setup() {
245
+ const current = ref(0)
246
+ return { current }
247
+ },
248
+ template: `
249
+ <div class="sb-canvas" style="padding: 20px;">
250
+ <rn-data-provider url="/api/tags" v-slot="{ data: tags, loading: tagsLoading }">
251
+ <rn-data-provider url="/api/products" :limit="48" v-slot="{ data: products, loading: productsLoading }">
252
+ <rn-stack v-if="tagsLoading || productsLoading" horizontal-re-size="fill" horizontal-align="center" vertical-align="center" style="min-height: 200px;">
253
+ <rn-spinner size="md" />
254
+ </rn-stack>
255
+ <rn-item-filter
256
+ v-else
257
+ :groups="tags"
258
+ :items="products"
259
+ :item-groups="(p) => p.label_texts"
260
+ all-label="すべて"
261
+ >
262
+ <template #default="{ filteredItems, groups, setActive }">
263
+ <rn-stack direction="vertical" horizontal-re-size="fill" gap="md">
264
+ <rn-tabs :modelValue="current" :is-scrollable="true">
265
+ <rn-tab
266
+ v-for="(g, index) in groups"
267
+ :key="g.key"
268
+ :label="g.label"
269
+ :active="g.isActive"
270
+ @click="current = index; setActive(g.key)"
271
+ />
272
+ </rn-tabs>
273
+ <rn-divider />
274
+ <rn-product-list :data="filteredItems" :pc-columns="4" :sp-columns="2" />
275
+ </rn-stack>
276
+ </template>
277
+ </rn-item-filter>
278
+ </rn-data-provider>
279
+ </rn-data-provider>
280
+ </div>
281
+ `,
282
+ }),
283
+ }
@@ -0,0 +1,133 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
+ import { ref } from 'vue'
3
+ import Pagination, {
4
+ type PaginationProps,
5
+ } from '@/components/elements/Pagination.vue'
6
+
7
+ const meta: Meta<typeof Pagination> = {
8
+ title: 'Elements/Pagination',
9
+ component: Pagination,
10
+ tags: ['autodocs'],
11
+ argTypes: {
12
+ totalPages: { control: 'number' },
13
+ siblingCount: { control: 'number' },
14
+ boundaryCount: { control: 'number' },
15
+ },
16
+ args: {
17
+ totalPages: 20,
18
+ siblingCount: 1,
19
+ boundaryCount: 1,
20
+ },
21
+ }
22
+
23
+ export default meta
24
+ type StoryArgs = PaginationProps & { currentPage?: number }
25
+ type Story = StoryObj<StoryArgs>
26
+ type OverridesStory = Omit<Story, 'argTypes'> & {
27
+ argTypes?: Record<string, any>
28
+ }
29
+
30
+ export const 基本: OverridesStory = {
31
+ args: {
32
+ totalPages: 20,
33
+ },
34
+ render: (args: StoryArgs) => ({
35
+ components: { 'rn-pagination': Pagination },
36
+ setup() {
37
+ const page = ref(1)
38
+ return { args, page }
39
+ },
40
+ template: /* html */ `
41
+ <div class='sb-canvas'>
42
+ <rn-pagination
43
+ v-model:current-page="page"
44
+ :total-pages="args.totalPages"
45
+ :sibling-count="args.siblingCount"
46
+ :boundary-count="args.boundaryCount"
47
+ />
48
+ <p style="margin-top: 16px; font-size: 14px; color: #666;">
49
+ 現在のページ: {{ page }}
50
+ </p>
51
+ </div>
52
+ `,
53
+ }),
54
+ }
55
+
56
+ export const SSRモード: OverridesStory = {
57
+ args: {
58
+ totalPages: 20,
59
+ },
60
+ render: (args: StoryArgs) => ({
61
+ components: { 'rn-pagination': Pagination },
62
+ setup() {
63
+ const page = ref(5)
64
+ const href = (p: number) => `#page=${p}`
65
+ return { args, page, href }
66
+ },
67
+ template: /* html */ `
68
+ <div class='sb-canvas'>
69
+ <rn-pagination
70
+ v-model:current-page="page"
71
+ :total-pages="args.totalPages"
72
+ :sibling-count="args.siblingCount"
73
+ :boundary-count="args.boundaryCount"
74
+ :href="href"
75
+ />
76
+ <p style="margin-top: 16px; font-size: 14px; color: #666;">
77
+ 現在のページ: {{ page }}(SSR: &lt;a&gt; タグでレンダリング)
78
+ </p>
79
+ </div>
80
+ `,
81
+ }),
82
+ }
83
+
84
+ export const ページ数が少ない: OverridesStory = {
85
+ args: {
86
+ totalPages: 5,
87
+ },
88
+ render: (args: StoryArgs) => ({
89
+ components: { 'rn-pagination': Pagination },
90
+ setup() {
91
+ const page = ref(3)
92
+ return { args, page }
93
+ },
94
+ template: /* html */ `
95
+ <div class='sb-canvas'>
96
+ <rn-pagination
97
+ v-model:current-page="page"
98
+ :total-pages="args.totalPages"
99
+ :sibling-count="args.siblingCount"
100
+ :boundary-count="args.boundaryCount"
101
+ />
102
+ <p style="margin-top: 16px; font-size: 14px; color: #666;">
103
+ 現在のページ: {{ page }}
104
+ </p>
105
+ </div>
106
+ `,
107
+ }),
108
+ }
109
+
110
+ export const _1ページのみ: OverridesStory = {
111
+ name: '1ページのみ',
112
+ args: {
113
+ totalPages: 1,
114
+ },
115
+ render: (args: StoryArgs) => ({
116
+ components: { 'rn-pagination': Pagination },
117
+ setup() {
118
+ const page = ref(1)
119
+ return { args, page }
120
+ },
121
+ template: /* html */ `
122
+ <div class='sb-canvas'>
123
+ <rn-pagination
124
+ v-model:current-page="page"
125
+ :total-pages="args.totalPages"
126
+ />
127
+ <p style="margin-top: 16px; font-size: 14px; color: #666;">
128
+ totalPages=1 のため非表示
129
+ </p>
130
+ </div>
131
+ `,
132
+ }),
133
+ }