From e01c06efd0b35750576a79b7fe5046b1fc21fc50 Mon Sep 17 00:00:00 2001
From: Xavier Carron <33637571+xav-car@users.noreply.github.com>
Date: Mon, 9 Sep 2024 12:53:04 +0200
Subject: [PATCH] feat(icon): add PixIcon Component
---
addon/components/pix-icon.hbs | 6 +++
addon/components/pix-icon.js | 45 +++++++++++++++++++
addon/helpers/icons.js | 77 +++++++++++++++++++++++++++++++++
app/components/pix-icon.js | 1 +
app/stories/pix-icon.mdx | 20 +++++++++
app/stories/pix-icon.stories.js | 51 ++++++++++++++++++++++
docs/update-sprites.mdx | 22 ++++++++++
7 files changed, 222 insertions(+)
create mode 100644 addon/components/pix-icon.hbs
create mode 100644 addon/components/pix-icon.js
create mode 100644 addon/helpers/icons.js
create mode 100644 app/components/pix-icon.js
create mode 100644 app/stories/pix-icon.mdx
create mode 100644 app/stories/pix-icon.stories.js
create mode 100644 docs/update-sprites.mdx
diff --git a/addon/components/pix-icon.hbs b/addon/components/pix-icon.hbs
new file mode 100644
index 000000000..06390370c
--- /dev/null
+++ b/addon/components/pix-icon.hbs
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/addon/components/pix-icon.js b/addon/components/pix-icon.js
new file mode 100644
index 000000000..0de6e7560
--- /dev/null
+++ b/addon/components/pix-icon.js
@@ -0,0 +1,45 @@
+import Component from '@glimmer/component';
+import { warn } from '@ember/debug';
+import { ICONS } from '@1024pix/pix-ui/helpers/icons';
+
+export default class PixIcon extends Component {
+ get alternativeText() {
+ return this.args.alternativeText || '';
+ }
+
+ get ariaHidden() {
+ warn(
+ 'PixIcon: @ariaHidden must be a true or nothing',
+ [true, false, null, undefined].includes(this.args.ariaHidden),
+ {
+ id: 'pix-ui.icon.aria-hidden.not-boolean',
+ },
+ );
+ console.log(this.args.ariaHidden);
+ return this.args.ariaHidden ? 'true' : undefined;
+ }
+
+ get iconName() {
+ warn(
+ `PixIcon: @name must be one of these : ${Object.keys(ICONS).join(' | ')}`,
+ Object.keys(ICONS).includes(this.args.name),
+ {
+ id: 'pix-ui.icon.not-valid',
+ },
+ );
+
+ warn(
+ 'PixIcon: @plainIcon must be a boolean, default undefined',
+ [true, false, undefined, null].includes(this.args.plainIcon),
+ {
+ id: 'pix-ui.icon.plan-icon.not-boolean',
+ },
+ );
+
+ const icon = ICONS[this.args.name];
+
+ if (!icon) return null;
+
+ return this.args.plainIcon && Boolean(icon.plainIcon) ? icon.plainIcon : icon.default;
+ }
+}
diff --git a/addon/helpers/icons.js b/addon/helpers/icons.js
new file mode 100644
index 000000000..0303f5784
--- /dev/null
+++ b/addon/helpers/icons.js
@@ -0,0 +1,77 @@
+export const ICONS = {
+ add: { default: 'add' },
+ arrowDown: { default: 'arrow_downward' },
+ arrowLeft: { default: 'arrow_back' },
+ arrowRight: { default: 'arrow_forward' },
+ arrowUp: { default: 'arrow_upward' },
+ assignment: { default: 'assignment', plainIcon: 'assignment_plainIcon' },
+ awards: { default: 'social_leaderboard', plainIcon: 'social_leaderboard_plainIcon' },
+ book: { default: 'menu_book', plainIcon: 'menu_book_plainIcon' },
+ bookmark: { default: 'bookmark', plainIcon: 'bookmark_plainIcon' },
+ buildings: { default: 'location_city' },
+ campaign: { default: 'campaign', plainIcon: 'campaign_plainIcon' },
+ cancel: { default: 'cancel', plainIcon: 'cancel_plainIcon' },
+ check: { default: 'check' },
+ checkCircle: { default: 'check_circle', plainIcon: 'check_circle_plainIcon' },
+ chevronDown: { default: 'arrow_drop_down' },
+ chevronLeft: { default: 'chevron_left' },
+ chevronRight: { default: 'chevron_right' },
+ chevronUp: { default: 'arrow_drop_up' },
+ close: { default: 'close' },
+ conversionPath: { default: 'conversion_path' },
+ copy: { default: 'content_copy', plainIcon: 'content_copy_plainIcon' },
+ delete: { default: 'delete', plainIcon: 'delete_plainIcon' },
+ down: { default: 'keyboard_arrow_down' },
+ download: { default: 'download' },
+ edit: { default: 'edit_square', plainIcon: 'edit_square_plainIcon' },
+ error: { default: 'error', plainIcon: 'error_plainIcon' },
+ extension: { default: 'extension', plainIcon: 'extension_plainIcon' },
+ eye: { default: 'visibility', plainIcon: 'visibility_plainIcon' },
+ eyeOff: { default: 'visibility_off', plainIcon: 'visibility_off_plainIcon' },
+ favorite: { default: 'favorite', plainIcon: 'favorite_plainIcon' },
+ flag: { default: 'flag', plainIcon: 'flag_plainIcon' },
+ globe: { default: 'globe' },
+ help: { default: 'help', plainIcon: 'help_plainIcon' },
+ home: { default: 'home', plainIcon: 'home_plainIcon' },
+ image: { default: 'image', plainIcon: 'image_plainIcon' },
+ info: { default: 'info', plainIcon: 'info_plainIcon' },
+ infoUser: { default: 'contact_page', plainIcon: 'contact_page_plainIcon' },
+ inventory: { default: 'inventory_2', plainIcon: 'inventory_2_plainIcon' },
+ language: { default: 'language' },
+ left: { default: 'arrow_back_ios' },
+ link: { default: 'link' },
+ lock: { default: 'lock', plainIcon: 'lock_plainIcon' },
+ mapPin: { default: 'location_on', plainIcon: 'location_on_plainIcon' },
+ minus: { default: 'check_indeterminate_small' },
+ moreHoriz: { default: 'more_horiz' },
+ moreVert: { default: 'more_vert' },
+ newRealease: { default: 'new_releases', plainIcon: 'new_releases_plainIcon' },
+ openNew: { default: 'open_in_new' },
+ pauseCircle: { default: 'pause_circle', plainIcon: 'pause_circle_plainIcon' },
+ playCircle: { default: 'play_circle', plainIcon: 'play_circle_plainIcon' },
+ power: { default: 'power_settings_new' },
+ readMore: { default: 'read_more' },
+ refresh: { default: 'refresh' },
+ right: { default: 'arrow_forward_ios' },
+ search: { default: 'search' },
+ seat: { default: 'airline_seat_recline_normal' },
+ session: { default: 'event_note', plainIcon: 'event_note_plainIcon' },
+ settings: { default: 'settings', plainIcon: 'settings_plainIcon' },
+ share: { default: 'share', plainIcon: 'share_plainIcon' },
+ shieldPerson: { default: 'shield_person', plainIcon: 'shield_person_plainIcon' },
+ signpost: { default: 'signpost', plainIcon: 'signpost_plainIcon' },
+ smartphone: { default: 'smartphone', plainIcon: 'smartphone_plainIcon' },
+ sort: { default: 'swap_vert' },
+ star: { default: 'star', plainIcon: 'star_plainIcon' },
+ stopCircle: { default: 'stop_circle', plainIcon: 'stop_circle_plainIcon' },
+ tablet: { default: 'tablet_android', plainIcon: 'tablet_android_plainIcon' },
+ thumbUp: { default: 'thumb_up', plainIcon: 'thumb_up_plainIcon' },
+ tools: { default: 'construction' },
+ up: { default: 'keyboard_arrow_up' },
+ upload: { default: 'upload' },
+ userCircle: { default: 'account_circle', plainIcon: 'account_circle_plainIcon' },
+ users: { default: 'group', plainIcon: 'group_plainIcon' },
+ volumeOff: { default: 'volume_off', plainIcon: 'volume_off_plainIcon' },
+ volumeOn: { default: 'volume_up', plainIcon: 'volume_up_plainIcon' },
+ warning: { default: 'warning', plainIcon: 'warning_plainIcon' },
+};
diff --git a/app/components/pix-icon.js b/app/components/pix-icon.js
new file mode 100644
index 000000000..a2994c5a4
--- /dev/null
+++ b/app/components/pix-icon.js
@@ -0,0 +1 @@
+export { default } from '@1024pix/pix-ui/components/pix-icon';
diff --git a/app/stories/pix-icon.mdx b/app/stories/pix-icon.mdx
new file mode 100644
index 000000000..904233ba5
--- /dev/null
+++ b/app/stories/pix-icon.mdx
@@ -0,0 +1,20 @@
+import { Meta, Story, ArgTypes } from '@storybook/blocks';
+import * as ComponentStories from './pix-icon.stories';
+
+
+
+# Pix Icon
+
+> Permet d'utiliser les icônes disponible du Design System.
+
+
+
+## Usage
+
+```html
+
+```
+
+## Arguments
+
+
diff --git a/app/stories/pix-icon.stories.js b/app/stories/pix-icon.stories.js
new file mode 100644
index 000000000..535ef17cf
--- /dev/null
+++ b/app/stories/pix-icon.stories.js
@@ -0,0 +1,51 @@
+import { hbs } from 'ember-cli-htmlbars';
+import { ICONS } from '../../addon/helpers/icons.js';
+
+export default {
+ title: 'Others/Icon',
+ argTypes: {
+ name: {
+ name: 'name',
+ description: "Nom de l'icône à utiliser",
+ type: { name: 'string', required: true },
+ control: { type: 'select' },
+ options: Object.keys(ICONS),
+ },
+ plainIcon: {
+ name: 'plainIcon',
+ description: "Permet d'utiliser la version pleine de l'icône",
+ control: { type: 'boolean' },
+ type: { name: 'boolean', required: false },
+ table: {
+ type: { summary: 'boolean' },
+ defaultValue: { summary: false },
+ },
+ },
+ alternativeText: {
+ name: 'alternativeText',
+ description: "Permet d'ajouter un texte alternatif pour illustrer l'icône si besoin",
+ type: { name: 'string', required: false },
+ },
+ ariaHidden: {
+ name: 'ariaHidden',
+ description:
+ "Permet de ne pas vocaliser l'icône au lecteur d'écran dans le cas d'une icône purement décorative.",
+ control: { type: 'boolean' },
+ type: { name: 'boolean', required: false },
+ table: {
+ type: { summary: 'boolean' },
+ defaultValue: { summary: false },
+ },
+ },
+ },
+};
+
+export const icon = (args) => ({
+ template: hbs``,
+ context: args,
+});
diff --git a/docs/update-sprites.mdx b/docs/update-sprites.mdx
new file mode 100644
index 000000000..6f7063a61
--- /dev/null
+++ b/docs/update-sprites.mdx
@@ -0,0 +1,22 @@
+import { Meta } from '@storybook/blocks';
+
+
+
+# Mise à jour du Sprites SVG
+
+## Récupération des nouveaux svg flat ( pas de téléchargement via Figma ou autre outils )
+
+La commande suivante permet de renommer les svgs si leur nom sont trop long :
+(actuellement Material Design export un SVG contenant toutes ses propriétés dans le nom, ce qui n'est pas util, surtout que le nom du fichier est utilisé pour générer un id dans le sprite)
+
+```shell
+./scripts/rename_svg_before_sprite.sh
+```
+
+Ensuite générer le `sprite.css.svg`
+
+```shell
+npm run svg:generate-sprite:no-cache
+```
+
+Effectuer le re-mapping des icons dans le composant `pix-icon` si besoin.