Skip to content

Commit 85468fb

Browse files
feat: dsw-2773 add select component (#253)
* feat: dsw-2773-add-select-shell * add examples * test imports * add proper imports * update examples * add form examples * update deps * update deps * update tests --------- Co-authored-by: Raouf <[email protected]>
1 parent 57256c7 commit 85468fb

File tree

21 files changed

+314
-115
lines changed

21 files changed

+314
-115
lines changed

nextjs-app-v14/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
},
1616
"dependencies": {
1717
"@justeattakeaway/pie-css": "0.16.0",
18-
"@justeattakeaway/pie-icons-webc": "1.6.2",
19-
"@justeattakeaway/pie-webc": "0.6.26",
18+
"@justeattakeaway/pie-icons-webc": "1.7.0",
19+
"@justeattakeaway/pie-webc": "0.6.28",
2020
"@lit-labs/nextjs": "0.2.0",
2121
"@lit/react": "1.0.6",
2222
"next": "14.2.18",

nextjs-app-v14/src/app/components/home-page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export default function HomePage() {
3434
<li><PieLink onClick={() => router.push('/components/radio-group')} tag="button">Radio Group</PieLink></li>
3535
<li><PieLink onClick={() => router.push('/components/spinner')} tag="button">Spinner</PieLink></li>
3636
<li><PieLink onClick={() => router.push('/components/switch')} tag="button">Switch</PieLink></li>
37+
<li><PieLink onClick={() => router.push('/components/select')} tag="button">Select</PieLink></li>
3738
<li><PieLink onClick={() => router.push('/components/tag')} tag="button">Tag</PieLink></li>
3839
<li><PieLink onClick={() => router.push('/components/text-input')} tag="button">Text Input</PieLink></li>
3940
<li><PieLink onClick={() => router.push('/components/textarea')} tag="button">Textarea</PieLink></li>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Select from './select';
2+
import { type Metadata } from 'next';
3+
4+
export const metadata: Metadata = {
5+
title: 'Select',
6+
}
7+
8+
export default function SelectComponent() {
9+
return <Select/>;
10+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use client';
2+
3+
import NavigationLayout from "@/app/layout/navigation";
4+
import { PieSelect, type SelectProps } from "@justeattakeaway/pie-webc/react/select.js";
5+
6+
export default function Select() {
7+
const options: SelectProps['options'] = [
8+
{
9+
tag: 'optgroup',
10+
label: 'Animals',
11+
options: [
12+
{
13+
tag: 'option',
14+
text: 'Cat',
15+
value: 'cat',
16+
},
17+
{
18+
tag: 'option',
19+
text: 'Dog',
20+
value: 'dog',
21+
},
22+
],
23+
},
24+
];
25+
26+
return (
27+
<NavigationLayout title="Select">
28+
<PieSelect options={options} />
29+
</NavigationLayout>
30+
);
31+
}

nextjs-app-v14/src/app/integrations/form/form.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { PieTextInput } from '@justeattakeaway/pie-webc/react/text-input.js';
1111
import { PieTextarea } from '@justeattakeaway/pie-webc/react/textarea.js';
1212
import { PieCheckbox } from '@justeattakeaway/pie-webc/react/checkbox.js';
1313
import { PieCheckboxGroup } from '@justeattakeaway/pie-webc/react/checkbox-group.js';
14+
import { PieSelect, SelectProps } from '@justeattakeaway/pie-webc/react/select.js';
1415
import { IconEmail } from '@justeattakeaway/pie-icons-webc/dist/react/IconEmail.js';
1516
import { IconLaptop } from '@justeattakeaway/pie-icons-webc/dist/react/IconLaptop.js';
1617
import { IconPhone } from '@justeattakeaway/pie-icons-webc/dist/react/IconPhone.js';
@@ -19,6 +20,19 @@ import { IconNumberSymbol } from '@justeattakeaway/pie-icons-webc/dist/react/Ico
1920
import { IconKey } from '@justeattakeaway/pie-icons-webc/dist/react/IconKey.js';
2021
import '@/styles/form.scss';
2122

23+
const foodOptions: SelectProps['options'] = [
24+
{
25+
tag: 'option',
26+
text: 'Select a value',
27+
value: '',
28+
},
29+
{
30+
tag: 'option',
31+
text: 'Burger',
32+
value: 'burger',
33+
}
34+
];
35+
2236
export default function Form() {
2337
const [approveSettings, setApproveSettings] = useState(false);
2438
const [enableNotifications, setNotifications] = useState(false);
@@ -28,6 +42,7 @@ export default function Form() {
2842
const [favouriteNumber, setFavouriteNumber] = useState('');
2943
const [favouriteNumberValidationMessage, setFavouriteNumberValidationMessage] = useState('');
3044
const [favouriteTakeaway, setFavouriteTakeaway] = useState('');
45+
const [favouriteFood, setFavouriteFood] = useState('');
3146

3247
const [formDataDisplay, setFormDataDisplay] = useState<string | null>(null);
3348

@@ -106,6 +121,10 @@ export default function Form() {
106121
setFavouriteTakeaway(newFavourite);
107122
}
108123

124+
const handleFavouriteFoodChange = (event: CustomEvent) => {
125+
setFavouriteFood(event.detail.sourceEvent.target.value);
126+
};
127+
109128
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
110129
event.preventDefault();
111130
const data = {
@@ -121,6 +140,7 @@ export default function Form() {
121140
tel,
122141
password,
123142
favouriteTakeaway,
143+
favouriteFood,
124144
description,
125145
};
126146

@@ -231,6 +251,18 @@ export default function Form() {
231251
value={description}
232252
onInput={handleDescriptionTextarea as any}/>
233253

254+
<PieFormLabel for="favouriteFood">
255+
Favourite Food:
256+
</PieFormLabel>
257+
<PieSelect
258+
className="form-field"
259+
id="favouriteFood"
260+
data-test-id="favouriteFood"
261+
name="favouriteFood"
262+
options={foodOptions}
263+
onChange={handleFavouriteFoodChange as any}
264+
/>
265+
234266
<div className="form-controls">
235267
<PieFormLabel for="approveSettings">
236268
Approve settings

nextjs-app-v14/test/visual/nextjs.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ describe('NextJS Aperture App', () => {
2323
{ url: '/components/radio-group', name: 'Radio Group' },
2424
{ url: '/components/spinner', name: 'Spinner' },
2525
{ url: '/components/switch', name: 'Switch' },
26+
{ url: '/components/select', name: 'Select' },
2627
{ url: '/components/tag', name: 'Tag' },
2728
{ url: '/components/text-input', name: 'Text Input' },
2829
{ url: '/components/textarea', name: 'Textarea' },

nuxt-app/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
},
2121
"dependencies": {
2222
"@justeattakeaway/pie-css": "0.16.0",
23-
"@justeattakeaway/pie-icons-webc": "1.6.2",
24-
"@justeattakeaway/pie-webc": "0.6.26",
23+
"@justeattakeaway/pie-icons-webc": "1.7.0",
24+
"@justeattakeaway/pie-webc": "0.6.28",
2525
"just-kebab-case": "4.2.0",
2626
"nuxt-ssr-lit": "1.6.27"
2727
},

nuxt-app/pages/components/select.vue

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<template>
2+
<pie-select :options="options"></pie-select>
3+
</template>
4+
5+
<script setup lang="ts">
6+
import { definePageMeta } from '#imports';
7+
import '@justeattakeaway/pie-webc/components/select.js';
8+
9+
definePageMeta({
10+
title: 'Select',
11+
});
12+
13+
const options = [
14+
{
15+
tag: 'optgroup',
16+
label: 'Animal',
17+
options: [
18+
{
19+
tag: 'option',
20+
text: 'Cat',
21+
value: 'cat',
22+
},
23+
{
24+
tag: 'option',
25+
text: 'Dog',
26+
value: 'dog',
27+
},
28+
],
29+
},
30+
];
31+
32+
</script>

nuxt-app/pages/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<li><pie-link href="/components/radio-group">Radio Group</pie-link></li>
2525
<li><pie-link href="/components/spinner">Spinner</pie-link></li>
2626
<li><pie-link href="/components/switch">Switch</pie-link></li>
27+
<li><pie-link href="/components/select">Select</pie-link></li>
2728
<li><pie-link href="/components/tag">Tag</pie-link></li>
2829
<li><pie-link href="/components/text-input">Text Input</pie-link></li>
2930
<li><pie-link href="/components/textarea">Textarea</pie-link></li>

nuxt-app/pages/integrations/form.vue

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@
102102
name="description">
103103
</pie-textarea>
104104

105+
<pie-form-label for="favouriteFood">
106+
Favourite Food:
107+
</pie-form-label>
108+
<pie-select
109+
@change="favouriteFood = $event.detail.sourceEvent.target.value"
110+
class="form-field"
111+
id="favouriteFood"
112+
data-test-id="favouriteFood"
113+
name="favouriteFood"
114+
:options="foodOptions">
115+
</pie-select>
116+
105117
<div class="form-controls">
106118
<pie-form-label for="approveSettings">
107119
Approve settings
@@ -187,6 +199,7 @@ import '@justeattakeaway/pie-webc/components/textarea.js';
187199
import '@justeattakeaway/pie-webc/components/radio.js';
188200
import '@justeattakeaway/pie-webc/components/radio-group.js';
189201
import '@justeattakeaway/pie-webc/components/switch.js';
202+
import '@justeattakeaway/pie-webc/components/select.js';
190203
import '@justeattakeaway/pie-webc/components/checkbox.js';
191204
import '@justeattakeaway/pie-webc/components/checkbox-group.js';
192205
import '@justeattakeaway/pie-icons-webc/dist/IconEmail.js';
@@ -216,6 +229,21 @@ const favouriteTakeaway = ref('');
216229
const contactByEmail = ref(false);
217230
const contactByPhone = ref(false);
218231
232+
const foodOptions = [
233+
{
234+
tag: 'option',
235+
text: 'Select a value',
236+
value: '',
237+
},
238+
{
239+
tag: 'option',
240+
text: 'Burger',
241+
value: 'burger',
242+
}
243+
];
244+
245+
const favouriteFood = ref('');
246+
219247
const formDataDisplay = ref('');
220248
221249
function handleFavouriteNumberInput(event: Event) {
@@ -246,6 +274,7 @@ function handleSubmit() {
246274
favouriteNumber: favouriteNumber.value,
247275
newsletterSignup: newsletter.value,
248276
description: description.value,
277+
favouriteFood: favouriteFood.value,
249278
contactByEmail: contactByEmail.value,
250279
contactByPhone: contactByPhone.value,
251280
}, null, 2);

nuxt-app/test/visual/nuxt.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ describe('Nuxt Aperture App', () => {
2323
{ url: '/components/radio-group', name: 'Radio Group' },
2424
{ url: '/components/spinner', name: 'Spinner' },
2525
{ url: '/components/switch', name: 'Switch' },
26+
{ url: '/components/select', name: 'Select' },
2627
{ url: '/components/tag', name: 'Tag' },
2728
{ url: '/components/text-input', name: 'Text Input' },
2829
{ url: '/components/textarea', name: 'Textarea' },

test/playwright/page-objects/form.page.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type TestFormData = {
1111
favouriteTakeaway: string;
1212
approveSettings: boolean;
1313
enableNotifications: boolean;
14+
favouriteFood: string;
1415
newsletterSignup: boolean;
1516
description: string;
1617
contactByEmail: boolean;
@@ -28,6 +29,7 @@ export class FormPage {
2829
readonly descriptionField: Locator;
2930
readonly approveSettingsSwitch: Locator;
3031
readonly enableNotificationsSwitch: Locator;
32+
readonly favouriteFood: Locator;
3133
readonly resetBtn: Locator;
3234
readonly submitBtn: Locator;
3335
readonly outputData: Locator;
@@ -47,6 +49,7 @@ export class FormPage {
4749
this.descriptionField = page.getByTestId('description');
4850
this.approveSettingsSwitch = page.getByTestId('approveSettings').getByTestId('switch-component');
4951
this.enableNotificationsSwitch = page.getByTestId('enableNotifications').getByTestId('switch-component');
52+
this.favouriteFood = page.getByTestId('favouriteFood');
5053
this.newsletterSignupCheckbox = page.getByTestId('newsletterSignup').getByTestId('pie-checkbox-label');
5154
this.contactByEmailCheckbox = page.getByTestId('contactByEmail').getByTestId('pie-checkbox-label');
5255
this.contactByPhoneCheckbox = page.getByTestId('contactByPhone').getByTestId('pie-checkbox-label');
@@ -73,6 +76,7 @@ export class FormPage {
7376
await this.descriptionField.locator('textarea').fill(formData.description);
7477
await this.approveSettingsSwitch.click();
7578
await this.enableNotificationsSwitch.click();
79+
await this.favouriteFood.locator('select').selectOption('burger');
7680
await this.newsletterSignupCheckbox.click();
7781
await this.favouriteTakeaway.click();
7882
await this.contactByEmailCheckbox.click();

test/system/form.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ test.describe(`Form Page - ${process.env.APP_NAME}`, () => {
1414
favouriteTakeaway: 'shawarma',
1515
approveSettings: true,
1616
enableNotifications: true,
17+
favouriteFood: "burger",
1718
newsletterSignup: true,
1819
description: 'foo',
1920
contactByEmail: true,

vanilla-app/components/select.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<load
2+
src="partials/page.html"
3+
title="Select"
4+
module="../js/select.js"
5+
/>

vanilla-app/integrations/form.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ <h1>Vanilla - PIE Form Test Page</h1>
4949
<pie-textarea class="form-field" id="description" data-test-id="description" name="description" placeholder="Write something about yourself...">
5050
</pie-textarea>
5151

52+
<pie-form-label for="favouriteFood">Favourite Food:</pie-form-label>
53+
<pie-select class="form-field" id="favouriteFood" data-test-id="favouriteFood" name="favouriteFood">
54+
</pie-select>
55+
5256
<div class="form-controls">
5357
<pie-switch label="Approve settings" id="approveSettings" data-test-id="approveSettings"
5458
name="approveSettings"></pie-switch>

vanilla-app/js/form.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import '@justeattakeaway/pie-webc/components/switch.js';
77
import '@justeattakeaway/pie-webc/components/checkbox.js';
88
import '@justeattakeaway/pie-webc/components/checkbox-group.js';
99
import '@justeattakeaway/pie-webc/components/form-label.js';
10+
import '@justeattakeaway/pie-webc/components/select.js';
1011
import '@justeattakeaway/pie-icons-webc/dist/IconEmail.js';
1112
import '@justeattakeaway/pie-icons-webc/dist/IconLaptop.js';
1213
import '@justeattakeaway/pie-icons-webc/dist/IconPhone.js';
@@ -21,6 +22,22 @@ import '../css/form.css';
2122
const form = document.querySelector('#testForm');
2223
const output = document.querySelector('#output');
2324
const favouriteNumberInput = document.querySelector('#favouriteNumber');
25+
const favouriteFoodSelect = document.querySelector('#favouriteFood');
26+
27+
const foodOptions = [
28+
{
29+
tag: 'option',
30+
text: 'Pizza',
31+
value: 'pizza',
32+
},
33+
{
34+
tag: 'option',
35+
text: 'Burger',
36+
value: 'burger',
37+
}
38+
];
39+
40+
favouriteFoodSelect.options = foodOptions;
2441

2542
favouriteNumberInput.addEventListener('input', (e) => {
2643
const value = parseInt(e.target.value, 10);

vanilla-app/js/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ document.querySelector('#navigation').innerHTML = `
2626
<li><pie-link href="/components/radio-group.html">Radio Group</pie-link></li>
2727
<li><pie-link href="/components/spinner.html">Spinner</pie-link></li>
2828
<li><pie-link href="/components/switch.html">Switch</pie-link></li>
29+
<li><pie-link href="/components/select.html">Select</pie-link></li>
2930
<li><pie-link href="/components/tag.html">Tag</pie-link></li>
3031
<li><pie-link href="/components/text-input.html">Text Input</pie-link></li>
3132
<li><pie-link href="/components/textarea.html">Textarea</pie-link></li>

vanilla-app/js/select.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import '@justeattakeaway/pie-webc/components/select.js';
2+
import './shared.js';
3+
import './utils/navigation.js';
4+
5+
const options = [
6+
{
7+
tag: 'optgroup',
8+
label: 'Animal',
9+
options: [
10+
{
11+
tag: 'option',
12+
text: 'Cat',
13+
value: 'cat',
14+
},
15+
{
16+
tag: 'option',
17+
text: 'Dog',
18+
value: 'dog',
19+
},
20+
],
21+
},
22+
];
23+
24+
document.querySelector('#app').innerHTML = `
25+
<pie-select id="animal-select"></pie-select>
26+
`;
27+
28+
document.querySelector('#animal-select').options = options;

vanilla-app/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
},
2020
"dependencies": {
2121
"@justeattakeaway/pie-css": "0.16.0",
22-
"@justeattakeaway/pie-icons-webc": "1.6.2",
23-
"@justeattakeaway/pie-webc": "0.6.26"
22+
"@justeattakeaway/pie-icons-webc": "1.7.0",
23+
"@justeattakeaway/pie-webc": "0.6.28"
2424
},
2525
"installConfig": {
2626
"hoistingLimits": "workspaces"

0 commit comments

Comments
 (0)