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(file-input): add file input component #1373

Merged
merged 23 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1c3343e
feat(file-input): add file input component
kevinbuhmann Apr 9, 2024
14bd45a
chore: update visual snapshots for `kevin/file-input`
web-flow Apr 23, 2024
e96f25e
pull request review changes
kevinbuhmann Apr 23, 2024
027c13e
Merge branch 'main' into kevin/file-input
kevinbuhmann Apr 23, 2024
02b2371
fix styles.md header
kevinbuhmann Apr 23, 2024
0658270
chore: update visual snapshots for `kevin/file-input`
web-flow Apr 23, 2024
a573279
add disabled file input to states story
kevinbuhmann Apr 23, 2024
684d43f
chore: update visual snapshots for `kevin/file-input`
web-flow Apr 23, 2024
a14c3e4
simplify browse button styles
kevinbuhmann Apr 23, 2024
4e4ebab
add value accessor (and other fixes/refactors)
kevinbuhmann Apr 23, 2024
5577eb0
remove TTestComponent type arg
kevinbuhmann Apr 23, 2024
39160ce
add .clr-file-input-browse-button-text to styles.md
kevinbuhmann Apr 23, 2024
ebc7aef
chore: update visual snapshots for `kevin/file-input`
web-flow Apr 23, 2024
bb90258
use selectFiles function in control spec
kevinbuhmann Apr 23, 2024
7ab9d29
no touch on init
kevinbuhmann Apr 23, 2024
c074101
chore: update visual snapshots for `kevin/file-input`
web-flow Apr 23, 2024
655bc86
accessibility fixes
kevinbuhmann Apr 24, 2024
ce2666c
update public api file
kevinbuhmann Apr 24, 2024
a22ad7e
Merge branch 'main' into kevin/file-input
kevinbuhmann May 7, 2024
af13f67
update clear files button aria label
kevinbuhmann May 7, 2024
4b85a80
update public api file
kevinbuhmann May 9, 2024
a176266
chore: update visual snapshots for `kevin/file-input`
web-flow May 9, 2024
c5c7505
Merge branch 'main' into kevin/file-input
kevinbuhmann May 20, 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
139 changes: 139 additions & 0 deletions .storybook/stories/file-input/file-input-states.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { FormsModule } from '@angular/forms';
import { ClrFileInputModule, ClrFormLayout } from '@clr/angular';
import { moduleMetadata, StoryContext, StoryFn, StoryObj } from '@storybook/angular';

import { clearFiles, selectFiles } from '../../../projects/angular/src/forms/file-input/file-input.helpers';

export default {
title: 'File Input/File Input States',
decorators: [
moduleMetadata({
imports: [FormsModule, ClrFileInputModule],
}),
],
argTypes: {
// form inputs
clrLayout: { control: false },
},
};

const fileInputStatesTemplate: StoryFn = args => ({
template: `
<form clrForm [clrLayout]="clrLayout">
<clr-file-input-container>
<label>Success State</label>
<input
id="success-state-file-input"
type="file"
name="success-state-file"
[(ngModel)]="successStateFile"
clrFileInput
required
multiple
/>
<clr-control-helper>Helper message</clr-control-helper>
<clr-control-success>Success message</clr-control-success>
<clr-control-error *clrIfError="'required'">Required</clr-control-error>
</clr-file-input-container>
<clr-file-input-container>
<label>Error State</label>
<input
id="error-state-file-input"
type="file"
name="error-state-file"
[(ngModel)]="errorStateFile"
clrFileInput
required
multiple
/>
<clr-control-helper>Helper message</clr-control-helper>
<clr-control-error *clrIfError="'required'">Required</clr-control-error>
</clr-file-input-container>
<clr-file-input-container>
<label>Multiple Files</label>
<input
id="multiple-files-file-input"
type="file"
name="multiple-files-file"
[(ngModel)]="multipleFilesFile"
clrFileInput
required
multiple
/>
<clr-control-helper>Helper message</clr-control-helper>
<clr-control-success>Success message</clr-control-success>
<clr-control-error *clrIfError="'required'">Required</clr-control-error>
</clr-file-input-container>
<clr-file-input-container>
<label>Long Filename</label>
<input
id="long-filename-file-input"
type="file"
name="long-filename-file"
[(ngModel)]="longFilenameFile"
clrFileInput
required
multiple
/>
<clr-control-helper>Helper message</clr-control-helper>
<clr-control-success>Success message</clr-control-success>
<clr-control-error *clrIfError="'required'">Required</clr-control-error>
</clr-file-input-container>
<clr-file-input-container>
<label>Disabled</label>
<input type="file" clrFileInput disabled />
</clr-file-input-container>
</form>
`,
props: { ...args },
});

export const VerticalFileInputStates: StoryObj = {
render: fileInputStatesTemplate,
play: fileInputStatesPlayFn,
args: {
clrLayout: ClrFormLayout.VERTICAL,
},
};

export const HorizontalFileInputStates: StoryObj = {
render: fileInputStatesTemplate,
play: fileInputStatesPlayFn,
args: {
clrLayout: ClrFormLayout.HORIZONTAL,
},
};

export const CompactFileInputStates: StoryObj = {
render: fileInputStatesTemplate,
play: fileInputStatesPlayFn,
args: {
clrLayout: ClrFormLayout.COMPACT,
},
};

function fileInputStatesPlayFn({ canvasElement }: StoryContext) {
const successStateFileInputElement = canvasElement.querySelector<HTMLInputElement>('#success-state-file-input');
selectFiles(successStateFileInputElement, [new File([''], 'file.txt')]);

const errorStateFileInputElement = canvasElement.querySelector<HTMLInputElement>('#error-state-file-input');
selectFiles(errorStateFileInputElement, [new File([''], 'file.txt')]);
clearFiles(errorStateFileInputElement);

const multipleFilesFileInputElement = canvasElement.querySelector<HTMLInputElement>('#multiple-files-file-input');
selectFiles(multipleFilesFileInputElement, [new File([''], 'file-1.txt'), new File([''], 'file-2.txt')]);

const longFilenameFileInputElement = canvasElement.querySelector<HTMLInputElement>('#long-filename-file-input');
selectFiles(longFilenameFileInputElement, [new File([''], 'long-filename-lorem-ipsum-dolor-sit-amet.txt')]);
}
65 changes: 65 additions & 0 deletions .storybook/stories/file-input/file-input.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { FormsModule } from '@angular/forms';
import { ClrFileInputModule, ClrFormLayout, commonStringsDefault } from '@clr/angular';
import { moduleMetadata, StoryFn, StoryObj } from '@storybook/angular';

export default {
title: 'File Input/File Input',
decorators: [
moduleMetadata({
imports: [FormsModule, ClrFileInputModule],
}),
],
argTypes: {
// inputs
clrButtonLabel: { type: 'string' },
// form inputs
clrLayout: { control: false },
},
args: {
// inputs
clrButtonLabel: commonStringsDefault.browse,
},
};

const fileInputTemplate: StoryFn = args => ({
template: `
<form clrForm [clrLayout]="clrLayout">
<clr-file-input-container [clrButtonLabel]="clrButtonLabel">
<label>File</label>
<input type="file" name="file" [(ngModel)]="file" clrFileInput required multiple />
<clr-control-helper>Helper message</clr-control-helper>
<clr-control-success>Success message</clr-control-success>
<clr-control-error *clrIfError="'required'">Required</clr-control-error>
</clr-file-input-container>
</form>
`,
props: { ...args },
});

export const VerticalFileInput: StoryObj = {
render: fileInputTemplate,
args: {
clrLayout: ClrFormLayout.VERTICAL,
},
};

export const HorizontalFileInput: StoryObj = {
render: fileInputTemplate,
args: {
clrLayout: ClrFormLayout.HORIZONTAL,
},
};

export const CompactFileInput: StoryObj = {
render: fileInputTemplate,
args: {
clrLayout: ClrFormLayout.COMPACT,
},
};
Loading
Loading