Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Search): api changes #2708

Merged
merged 36 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7978a2b
feat(Search): api changes
Barsnes Oct 30, 2024
735100b
more work, start new API
Barsnes Oct 30, 2024
3d721a2
use less classnames and misc
Barsnes Oct 30, 2024
f17016f
chnageevent
Barsnes Oct 30, 2024
9509d13
only one css class
Barsnes Oct 31, 2024
878446a
tests, last css
Barsnes Oct 31, 2024
e21c9fa
css var clean
Barsnes Oct 31, 2024
139b533
less js checks
Barsnes Oct 31, 2024
c6bc083
lets not omit size..
Barsnes Oct 31, 2024
18cc755
Merge branch 'next' into form/search
Barsnes Nov 1, 2024
3047f8c
more cleaning
Barsnes Nov 1, 2024
75c108e
docs, misc, etc
Barsnes Nov 1, 2024
f5577f6
brand new shiny api
Barsnes Nov 1, 2024
77014dd
remove dummy story
Barsnes Nov 1, 2024
97aa7af
Merge branch 'next' into form/search
Barsnes Nov 1, 2024
bfbdec3
cleaning
Barsnes Nov 1, 2024
58a9ad4
some docs
Barsnes Nov 1, 2024
13a473c
fix showcase
Barsnes Nov 1, 2024
d9a73f7
jsdoc
Barsnes Nov 1, 2024
c79763c
Create few-squids-speak.md
Barsnes Nov 1, 2024
b294978
a lot of misc
Barsnes Nov 1, 2024
b012108
display none
Barsnes Nov 1, 2024
29b9c63
inline-X/Y
Barsnes Nov 1, 2024
72ba1dd
correct y spacing
Barsnes Nov 1, 2024
f2d3935
double rest and classname
Barsnes Nov 4, 2024
8c2f1ee
Merge branch 'next' into form/search
Barsnes Nov 4, 2024
9431de0
misc props and send `className`
Barsnes Nov 4, 2024
a9d8cb1
changes from #2723
Barsnes Nov 4, 2024
2a11f9b
target both submit and button
Barsnes Nov 4, 2024
1634693
jsdoc
Barsnes Nov 4, 2024
10ace87
dont require aria label, but till in docs
Barsnes Nov 4, 2024
9c022f3
css
Barsnes Nov 4, 2024
2f144aa
remove id
Barsnes Nov 4, 2024
f16b7a5
css
Barsnes Nov 5, 2024
ce2587c
selectors, again
Barsnes Nov 5, 2024
20baf68
Merge branch 'next' into form/search
Barsnes Nov 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/few-squids-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@digdir/designsystemet-css": major
"@digdir/designsystemet-react": major
---

Search: New compound API
233 changes: 83 additions & 150 deletions packages/css/search.css
Original file line number Diff line number Diff line change
@@ -1,170 +1,103 @@
.ds-search {
--dsc-search-padding-inline-x: var(--ds-spacing-2);
--dsc-search-padding-inline-y: var(--ds-spacing-3);
--dsc-search-clear-button-size: var(--ds-sizing-6);
--dsc-search-input-background: var(--ds-color-neutral-background-default);
--dsc-search-input-border-color: var(--ds-color-neutral-border-default);
--dsc-search-input-border: 1px solid var(--dsc-search-input-border-color);
--dsc-search-input-color: var(--ds-color-neutral-text-default);
--dsc-search-input-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath d='M10.5 3.25a7.25 7.25 0 1 0 4.57 12.88l5.41 5.41a.75.75 0 1 0 1.06-1.06l-5.41-5.41A7.25 7.25 0 0 0 10.5 3.25M4.75 10.5a5.75 5.75 0 1 1 11.5 0 5.75 5.75 0 0 1-11.5 0'/%3E%3C/svg%3E");
--dsc-search-clear-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='currentColor' d='M6.53 5.47a.75.75 0 0 0-1.06 1.06L10.94 12l-5.47 5.47a.75.75 0 1 0 1.06 1.06L12 13.06l5.47 5.47a.75.75 0 1 0 1.06-1.06L13.06 12l5.47-5.47a.75.75 0 0 0-1.06-1.06L12 10.94z'/%3E%3C/svg%3E");
--dsc-search-icon-size: var(--ds-sizing-7);
--dsc-search-clear-icon-size: var(--ds-sizing-9);

display: inline-grid;
display: grid;
grid-template-columns: 1fr auto;
width: 100%;
gap: var(--ds-spacing-2);
}

.ds-search--sm {
--dsc-search-clear-button-size: var(--ds-sizing-5);
}

.ds-search--md {
--dsc-search-clear-button-size: var(--ds-sizing-6);
}

.ds-search--lg {
--dsc-search-clear-button-size: var(--ds-sizing-8);
}

.ds-search__label {
min-width: min-content;
display: inline-flex;
flex-direction: row;
gap: var(--ds-spacing-1);
align-items: center;
}

.ds-search__field {
display: flex;
width: 100%;
align-items: stretch;
border-radius: var(--ds-border-radius-default);
position: relative;
}

.ds-search__icon {
position: absolute;
height: 100%;
z-index: 2;
left: var(--ds-spacing-4);
transform: scale(1.5);
pointer-events: none;
}

[type='search']::-webkit-search-decoration,
[type='search']::-webkit-search-cancel-button {
appearance: none;
}

.ds-search__input {
background: var(--dsc-search-input-background);
color: var(--dsc-search-input-color);
border: var(--dsc-search-input-border);
border-radius: var(--ds-border-radius-default);
font-family: inherit;
position: relative;
box-sizing: border-box;
flex: 0 1 auto;
height: 100%;
width: 100%;
appearance: none;
padding: 0 var(--ds-spacing-3);
}

.ds-search__input.ds-search__input--with-search-button {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}

.ds-search__input:disabled {
cursor: not-allowed;
}

.ds-search__input[type='search']:focus-visible {
z-index: 1;
}

.ds-search:has(.ds-search__input:disabled) {
opacity: var(--ds-disabled-opacity);
}

.ds-search__search-button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}

.ds-search__search-button:not(:focus-visible) {
border-left: 0;
}

.ds-search__search-button:focus-visible {
z-index: 1;
}

.ds-search__clear-button {
color: var(--ds-color-neutral-text-default);
display: inline-flex;
align-items: center;
justify-content: center;
position: absolute;
background: none;
border: none;
right: 0.6em;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
height: var(--dsc-search-clear-button-size);
width: var(--dsc-search-clear-button-size);
border-radius: var(--ds-border-radius-default);
font-size: 1.25rem;
padding: 0;
z-index: 2;
}

.ds-search--sm .ds-search__input {
--dsc-search-clear-button-size: var(--ds-sizing-4);

height: var(--ds-sizing-10);
padding: 0 var(--ds-spacing-3);
padding-right: 2.5em;
}

.ds-search--sm .ds-search__icon {
left: var(--ds-spacing-3);
}
/* Moves the focused element to the top, so it is not hidden by an adjacent element */
&:focus-visible {
z-index: 1;
}

.ds-search--md .ds-search__input {
--dsc-search-clear-button-size: var(--ds-sizing-6);
& input {
padding-inline: var(--dsc-search-padding-inline-x) var(--dsc-search-padding-inline-y);
}

height: var(--ds-sizing-12);
padding: 0 var(--ds-spacing-4);
padding-right: 2.2em;
}
/* The simple variant, when no submit button is present */
&:not(:has(button[type='submit'])) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we maybe not select on type incase someone changes it to type="button"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah we should probably nmot 🤔 Maybe we can select on both

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&:not(:has(button:not([type='reset'])))? :D

& input {
padding-left: 2.4em;
}

&::before {
content: '';
position: absolute;
margin-inline: var(--dsc-search-padding-inline-x) var(--dsc-search-padding-inline-y);
top: 50%;
transform: translateY(-50%);
height: var(--dsc-search-icon-size);
aspect-ratio: 1 / 1;
mask: var(--dsc-search-input-icon) center / contain no-repeat;
background: currentcolor;
z-index: 2;
}
}

.ds-search--md .ds-search__icon {
left: var(--ds-spacing-4);
}
& input {
grid-area: 1 / 1;

.ds-search--lg .ds-search__input {
--dsc-search-clear-button-size: var(--ds-sizing-12);
&::-webkit-search-decoration,
&::-webkit-search-cancel-button {
appearance: none;
}
}

height: var(--ds-sizing-14);
padding: 0 var(--ds-spacing-5);
padding-right: 2em;
}
/* We hide the clear button when input is empty */
&:has(input:placeholder-shown) button[type='reset'],
&:has(input:is(:read-only, :disabled, [aria-disabled='true'])) button[type='reset'] {
display: none;
}

.ds-search--lg .ds-search__icon {
left: var(--ds-spacing-5);
}
&:has(button[type='reset']) {
& input {
padding-inline-end: calc(var(--dsc-search-clear-button-size) + var(--dsc-search-padding-inline-x) * 2);
}
}

.ds-search__input.ds-search__input--simple {
padding-left: 2.4em;
}
& button[type='reset'] {
grid-area: 1 / 1;
justify-self: end;
align-self: center;
margin-inline-end: calc(var(--dsc-search-padding-inline-x) * 2);
height: var(--dsc-search-clear-button-size);
width: var(--dsc-search-clear-button-size);
font-size: 0.5em;
z-index: 2;
position: relative;

&::before {
content: '';
height: var(--dsc-search-clear-icon-size);
width: var(--dsc-search-clear-icon-size);
mask: var(--dsc-search-clear-icon) center / contain no-repeat;
background: currentcolor;
z-index: 2;
pointer-events: none;
}
}

@media (hover: hover) and (pointer: fine) {
.ds-search__input:not(:focus-visible, :disabled, [aria-disabled]):hover {
--dsc-search-input-border-color: var(--ds-color-accent-border-strong);
& button[type='submit'] {
border-top-left-radius: 0;
border-bottom-left-radius: 0;

box-shadow: inset 0 0 0 1px var(--ds-color-accent-border-strong);
&:not(:focus-visible) {
border-left: 0;
}
}

.ds-search__clear-button:not(:focus-visible, :disabled, [aria-disabled]):hover {
background: var(--ds-color-accent-surface-hover);
&:has(button[type='submit']) {
& input {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
}
31 changes: 25 additions & 6 deletions packages/react/src/components/form/Search/Search.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,39 @@ import * as SearchStories from './Search.stories';
<Primary />
<Controls />

## Slik bruker du Search

Du velger selv om du vil bruke `Search.Clear` og `Search.Button`. Vi anbefaler at du bruker `Search.Clear` for å gi brukeren mulighet til å fjerne søket.
Dersom du ikke har `Search.Button` vil input feltet få et søkeikon.

`ara-label` eller `aria-labelledby` er påkrevd på `Search.Input`.

```tsx
import { Search } from '@digdir/designsystemet-react';

<Search>
<Search.Input aria-label="Sæk" />
<Search.Clear />
<Search.Button />
</Search.Clear>
```

## Kontrollert

<Canvas of={SearchStories.Controlled} />

## Full bredde
## Varianter

Du kan endre `variant` på `Button`, eller ta den bort for å få forskjellige varianter.

<Canvas of={SearchStories.FullWidth} />
<Canvas of={SearchStories.Variants} />

## Ikon søkeknapp
## Med Label

Bruk `searchButtonLabel` og `clearButtonLabel` til å sett innholdet i knappene på `Search`.
Ønsker du å bruke kun et ikon på søkeknappen, sørg for at den har `title` definert.
Dersom du vil ha label på søkefeltet, må du legge til en `Label` komponent som du kobler sammen med `aria-labelledby` på `Search`.
I eksempelet har vi brukt `Field` for å få oppkobling mellom `Label` og `Search.Input`.

<Canvas of={SearchStories.OnlyIcon} />
<Canvas of={SearchStories.WithLabel} />

## Skjema

Expand Down
Loading
Loading