Skip to content

Commit

Permalink
feat(interface): ✨ add light mode (#52)
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit b023660
Author: James <james@jamesnzl.xyz>
Date:   Fri Jul 15 00:01:34 2022 +1200

    chore(assets): :bento: update screenshots

commit 7b14700
Merge: ca6b988 909e8ab
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 23:55:16 2022 +1200

    Merge branch 'main' into light-mode

commit ca6b988
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 23:47:10 2022 +1200

    docs(readme): :memo: add `Theme` option

commit 57830c3
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 23:36:52 2022 +1200

    feat(options): :children_crossing: toggle display theme on input

commit 8013ef1
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 23:24:41 2022 +1200

    refactor(options): :bulb: add heading comments

commit 939d3c0
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 23:19:57 2022 +1200

    feat(interface): :lipstick: set display theme on load

commit f8b70bf
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 22:38:49 2022 +1200

    refactor(options): :wrench: modify theme saved values configuration

commit f35a167
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 22:22:03 2022 +1200

    feat(elements): :sparkles: create `SegmentedControl` element (#51)
    
    Squashed commit of the following:
    
    commit 479944f
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 22:19:25 2022 +1200
    
        feat(elements): :art: use generic to constrain `SupportedTypes`
    
    commit 413dd97
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 22:15:03 2022 +1200
    
        refactor(elements): :art: export `SegmentedControl` from `./elements`
    
    commit 079b1c0
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 22:11:54 2022 +1200
    
        refactor(options): :art: refactor `AdvancedOptions`
    
    commit b04f9ce
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 22:03:22 2022 +1200
    
        fix(elements): :bug: fix stack overflow
    
    commit 4dde75a
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 21:57:22 2022 +1200
    
        feat(options): :wrench: configure segmented controls
    
    commit ecc54da
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 21:39:08 2022 +1200
    
        feat(elements): :label: make `default` and `showDependents` optional
    
    commit e57437d
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 21:34:09 2022 +1200
    
        feat(elements): :technologist: add generic to constrain segment ids
    
    commit fab3a05
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 21:31:12 2022 +1200
    
        feat(elements): :sparkles: implement bones of `SegmentedControl`
    
    commit 95d03e3
    Author: James <james@jamesnzl.xyz>
    Date:   Thu Jul 14 20:32:54 2022 +1200
    
        refactor(elements): :construction: change segmented inputs from `Input` class

commit 8813b22
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 20:02:14 2022 +1200

    feat(options): :construction: add wip configuration for display theme

commit bbbffa0
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 19:46:28 2022 +1200

    feat(interface): :lipstick: add theme to options page

commit 0500e54
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 19:26:43 2022 +1200

    feat(interface): :lipstick: use `prefers-color-scheme` for default theme

commit 167dc2b
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 19:18:16 2022 +1200

    feat(interface): :lipstick: tweak light mode colours

commit 7902335
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 18:42:01 2022 +1200

    fix(sass): :bug: compute shadow values at build time

commit 078c10f
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 18:30:53 2022 +1200

    feat(sass): :lipstick: generate custom properties for dark mode

commit d998bc8
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 18:27:41 2022 +1200

    fix(sass): :bug: use sass function to generate map

commit ff93b71
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 17:46:30 2022 +1200

    refactor(sass): :art: use mixin to generate custom properties

commit 01c9d23
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 17:44:39 2022 +1200

    refactor(sass): :recycle: group theme namespace into `$theme` map

commit 0ecfa68
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 17:13:52 2022 +1200

    build(gulp): :wrench: glob nested `.scss` files

commit 91284e8
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 16:57:25 2022 +1200

    refactor(sass): :art: refactor shadow calculations

commit 7977630
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 16:53:28 2022 +1200

    refactor(sass): :recycle: use css custom properties

commit c50c792
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 16:46:25 2022 +1200

    refactor(sass): :truck: move themes to `themes/`

commit 66d350a
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 16:36:00 2022 +1200

    feat(interface): :lipstick: darken light mode code text colour

commit 1338ae1
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 16:21:46 2022 +1200

    refactor(sass): :recycle: refactor colour calculations into variables

commit cac3561
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 16:13:06 2022 +1200

    refactor(stylesheet): :lipstick: parameterise red button shadow

commit db2b7d2
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 15:31:29 2022 +1200

    feat(interface): :lipstick: make light element scrollbar more subtle

commit 9ec1267
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 15:29:40 2022 +1200

    feat(interface): :lipstick: add dark mode theme

commit cca01ad
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 12:11:43 2022 +1200

    refactor(sass): :art: organise `_variables`

commit 52a2012
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 03:23:19 2022 +1200

    feat(interface): :lipstick: tweak light mode colours

commit e021c61
Author: James <james@jamesnzl.xyz>
Date:   Thu Jul 14 03:06:44 2022 +1200

    feat(interface): :lipstick: adjust element active colour

commit 6ae9f9c
Author: James <james@jamesnzl.xyz>
Date:   Wed Jul 13 21:32:28 2022 +1200

    refactor(stylesheet): :art: change order to match `_variables`

commit 0fa1b2d
Author: James <james@jamesnzl.xyz>
Date:   Wed Jul 13 21:31:50 2022 +1200

    feat(interface): :lipstick: don't hardcode button text colours

commit e62c536
Author: James <james@jamesnzl.xyz>
Date:   Wed Jul 13 21:30:09 2022 +1200

    feat(interface): :lipstick: explicitly style scrollbar colours

commit 1e40b34
Author: James <james@jamesnzl.xyz>
Date:   Wed Jul 13 21:29:18 2022 +1200

    feat(interface): :lipstick: style light mode colours

commit b54434f
Author: James <james@jamesnzl.xyz>
Date:   Wed Jul 13 21:26:57 2022 +1200

    feat(interface): :lipstick: add shadow multiplier

commit 61cf232
Author: James <james@jamesnzl.xyz>
Date:   Mon Jul 11 20:31:41 2022 +1200

    build(gulp): 📦 add `postcss` to build system (#49)
    
    Squashed commit of the following:
    
    commit f51c197
    Author: James <james@jamesnzl.xyz>
    Date:   Mon Jul 11 14:04:31 2022 +1200
    
        build(gulp): :package: add `postcss` to build system
    
    commit dd0389f
    Author: James <james@jamesnzl.xyz>
    Date:   Mon Jul 11 13:49:18 2022 +1200
    
        chore(gulp): :bug: fix `Source[]` type
    
    commit 006168d
    Author: James <james@jamesnzl.xyz>
    Date:   Mon Jul 11 13:05:56 2022 +1200
    
        build(deps-dev): :heavy_minus_sign: remove `gulp-autoprefixer`
    
    commit 4a55711
    Author: James <james@jamesnzl.xyz>
    Date:   Mon Jul 11 13:05:37 2022 +1200
    
        build(deps-dev): :heavy_plus_sign: install `autoprefixer`
    
    commit 03fd035
    Author: James <james@jamesnzl.xyz>
    Date:   Mon Jul 11 13:05:11 2022 +1200
    
        build(deps-dev): :heavy_plus_sign: install `cssnano`
    
    commit a9ad397
    Author: James <james@jamesnzl.xyz>
    Date:   Mon Jul 11 11:35:59 2022 +1200
    
        build(deps-dev): :heavy_plus_sign: install `gulp-postcss`
    
    commit c9dddf1
    Author: James <james@jamesnzl.xyz>
    Date:   Mon Jul 11 11:35:11 2022 +1200
    
        build(deps-dev): :heavy_plus_sign: install `postcss`

commit 0a9df41
Author: James <james@jamesnzl.xyz>
Date:   Sun Jul 10 21:57:05 2022 +1200

    refactor(stylesheet): :fire: remove redundant styles

commit 56854dd
Merge: 586121d 97b83b9
Author: James <james@jamesnzl.xyz>
Date:   Sun Jul 10 16:48:43 2022 +1200

    refactor(sass): :recycle: nest selectors

commit 586121d
Author: James <james@jamesnzl.xyz>
Date:   Sun Jul 10 16:33:15 2022 +1200

    refactor(stylesheet): :art: remove hardcoded colour values

commit 2013b82
Author: James <james@jamesnzl.xyz>
Date:   Sun Jul 10 16:10:24 2022 +1200

    refactor(stylesheet): :truck: rename colour variables
  • Loading branch information
JamesNZL committed Jul 14, 2022
1 parent 3bb9baa commit 2404a1a
Show file tree
Hide file tree
Showing 24 changed files with 702 additions and 166 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ chmod +x /Users/YOUR_USERNAME/Downloads/Notion\ Canvas\ Assignment\ Import/Conte

| Option | Purpose/Remarks |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `Theme` | Whether to use `Light`/`Dark` mode, or use the browser's default (`System`). |
| `Show Advanced Options` | Whether to `Show`/`Hide` the **Advanced Options**. |
| `Timezone` | The `TZ` timezone in which to parse and set all dates |
| `Internal Integration Token` (**Safari only**) | The `Internal Integration Token` of your Notion integration |
Expand Down
Binary file modified assets/screenshots/options1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshots/options2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshots/options3.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion build/gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const sources = {
],
style: [
{
glob: `${CONFIGURATION.DIRECTORIES.SOURCE}/style/*.scss`,
glob: `${CONFIGURATION.DIRECTORIES.SOURCE}/style/**/*.scss`,
base: `${CONFIGURATION.DIRECTORIES.SOURCE}/style`,
},
],
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@
}
]
}
}
}
3 changes: 3 additions & 0 deletions src/apis/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ export const Storage = <const>{

return {
timeZone: savedFields['timeZone'],
extension: {
displayTheme: savedFields['extension.displayTheme'],
},
popup: {
displayJSONButton: savedFields['popup.displayJSONButton'],
},
Expand Down
101 changes: 101 additions & 0 deletions src/elements/SegmentedControl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Element } from './Element';
import { Input } from './Input';

import { SupportedTypes } from '../options/configuration';

interface Segment<T, V> {
id: T;
value: V;
default?: boolean;
showDependents?: boolean;
}

type Segments<T, V> = (
Segment<T, V> & {
input: Input;
}
)[];

export class SegmentedControl extends Element {
private segments: Segments<string, SupportedTypes>;

private constructor(id: string, type = 'segmented control', segments: Segment<string, SupportedTypes>[]) {
super(id, type);

this.segments = segments.map(segment => ({
...segment,
input: Input.getInstance(segment.id, 'segmented control input'),
}));
}

public static override getInstance<T extends string, V extends SupportedTypes>(id: T, type = 'segmented control', segments?: Segment<T, V>[]): SegmentedControl {
if (!segments) throw new Error(`You must declare the segments for this SegmentedControl ${id}!`);

return SegmentedControl.instances[id] = (SegmentedControl.instances[id] instanceof SegmentedControl)
? <SegmentedControl>SegmentedControl.instances[id]
: new SegmentedControl(id, type, segments);
}

public async validate() {
return await this.getValue();
}

private getCheckedSegment() {
return this.element.querySelector('input:checked');
}

public getValue(): SupportedTypes {
const checkedSegment = this.getCheckedSegment();

if (!checkedSegment) return this.segments.find(segment => Boolean(segment.default))?.value ?? null;

return this.segments.find(({ id }) => id === checkedSegment.id)?.value ?? null;
}

public setValue(value: SupportedTypes, dispatchEvent = true) {
const segmentToCheck = this.segments.find(segment => segment.value === value);

if (!segmentToCheck) throw new Error(`Failed to set unexpected value ${value} of type ${typeof value} on segmented control ${this.id}`);

segmentToCheck.input.setValue(true, false);

if (!dispatchEvent) return;
this.dispatchInputEvent();
}

public override show() {
super.show();
this.dispatchInputEvent();
}

public override hide() {
super.hide();
this.dispatchInputEvent();
}

public dispatchInputEvent(bubbles?: boolean) {
this.dispatchEvent(new Event('input', { bubbles }));
}

public toggleDependents(dependents: readonly string[]) {
const checkedSegment = this.getCheckedSegment();

const showDependents = this.segments.find(({ id }) => id === checkedSegment?.id)?.showDependents;

if (!checkedSegment || this.isHidden() || !showDependents) {
dependents.forEach(dependentId => {
const dependent = Element.getInstance(dependentId, 'dependent');
dependent.hide();
dependent.dispatchEvent(new Event('input', { bubbles: true }));
});

return;
}

dependents.forEach(dependentId => {
const dependent = Element.getInstance(dependentId, 'dependent');
dependent.show();
dependent.dispatchEvent(new Event('input', { bubbles: true }));
});
}
}
1 change: 1 addition & 0 deletions src/elements/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { Button } from './Button';
export { Input } from './Input';
export { Select } from './Select';
export { KeyValueGroup } from './KeyValueGroup';
export { SegmentedControl } from './SegmentedControl';

export function getElementById<T extends string>(id: T): HTMLElement | null {
return document.getElementById(id);
Expand Down
64 changes: 58 additions & 6 deletions src/options/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Input, KeyValueGroup } from '../elements';
import { Input, KeyValueGroup, SegmentedControl } from '../elements';

import { NullIfEmpty, SavedFields, SavedOptions } from './';
import {
Expand Down Expand Up @@ -36,7 +36,6 @@ interface Dependable {
interface Subscribable {
addEventListener(...args: Parameters<typeof HTMLElement.prototype.addEventListener>): void;
dispatchInputEvent(bubbles?: boolean): void;

}

interface HasPlaceholder {
Expand Down Expand Up @@ -68,8 +67,16 @@ type IncompleteFieldKey<K extends string> = K extends keyof SavedFields

interface InputElements {
'timeZone': 'timezone';
'popup.displayJSONButton': 'show-json-button';
'options.displayAdvanced': 'show-advanced-options';
'extension.displayTheme': 'display-theme';
displaySystemMode: 'display-system-mode';
displayLightMode: 'display-light-mode';
displayDarkMode: 'display-dark-mode';
'popup.displayJSONButton': 'display-json-button';
hideJSONButton: 'hide-json-button';
showJSONButton: 'show-json-button';
'options.displayAdvanced': 'display-advanced-options';
hideAdvancedOptions: 'hide-advanced-options';
showAdvancedOptions: 'show-advanced-options';
'canvas.classNames.breadcrumbs': 'breadcrumbs';
'canvas.classNames.assignment': 'assignment-class';
'canvas.classNames.title': 'assignment-title';
Expand Down Expand Up @@ -127,12 +134,46 @@ export const CONFIGURATION: {
return this.input = Input.getInstance<InputElementId>('timezone', 'input', TimeZoneField);
},
},
extension: {
displayTheme: {
defaultValue: null,
get input() {
delete (<Partial<typeof this>>this).input;
return this.input = SegmentedControl.getInstance<InputElementId, typeof this.defaultValue>('display-theme', 'segmented control', [
{
id: 'display-system-mode',
value: null,
default: true,
},
{
id: 'display-light-mode',
value: 'light',
},
{
id: 'display-dark-mode',
value: 'dark',
},
]);
},
},
},
popup: {
displayJSONButton: {
defaultValue: false,
get input() {
delete (<Partial<typeof this>>this).input;
return this.input = Input.getInstance<InputElementId>('show-json-button', 'input');
return this.input = SegmentedControl.getInstance<InputElementId, typeof this.defaultValue>('display-json-button', 'segmented control', [
{
id: 'hide-json-button',
value: false,
default: true,
},
{
id: 'show-json-button',
value: true,
showDependents: true,
},
]);
},
},
},
Expand All @@ -141,7 +182,18 @@ export const CONFIGURATION: {
defaultValue: false,
get input() {
delete (<Partial<typeof this>>this).input;
return this.input = Input.getInstance<InputElementId>('show-advanced-options', 'input');
return this.input = SegmentedControl.getInstance<InputElementId, typeof this.defaultValue>('display-advanced-options', 'segmented control', [
{
id: 'hide-advanced-options',
value: false,
default: true,
},
{
id: 'show-advanced-options',
value: true,
showDependents: true,
},
]);
},
},
},
Expand Down
4 changes: 4 additions & 0 deletions src/options/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type NeverEmpty<T extends string> = T extends '' ? never : T;
type NullIfEmpty<T extends string | null> = (T extends '' ? null : T) | null;

interface RequiredFields {
'extension.displayTheme': null | 'light' | 'dark';
'popup.displayJSONButton': boolean;
'options.displayAdvanced': boolean;
'canvas.classNames.breadcrumbs': NeverEmpty<string>;
Expand Down Expand Up @@ -46,6 +47,9 @@ export type SavedFields = RequiredFields & OptionalFields;
*/
export type SavedOptions = {
timeZone: OptionalFields['timeZone'];
extension: {
displayTheme: RequiredFields['extension.displayTheme'];
};
popup: {
displayJSONButton: RequiredFields['popup.displayJSONButton'];
};
Expand Down
21 changes: 20 additions & 1 deletion src/options/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ <h1>Notion Assignment Import</h1>
<div>
<h1>Extension Options</h1>

<h3>Appearance</h3>
<div class='tile'>
<div>
<label class='required' for='display-theme'>Theme</label>
<div class='segmented-control-wrapper'>
<div class='segmented-control-triple row' id='display-theme'>
<input checked type='radio' name='display-theme' value='display-system-mode' id='display-system-mode'>
<label for='display-system-mode'>System</label>

<input type='radio' name='display-theme' value='display-light-mode' id='display-light-mode'>
<label for='display-light-mode'>Light</label>

<input type='radio' name='display-theme' value='display-dark-mode' id='display-dark-mode'>
<label for='display-dark-mode'>Dark</label>
</div>
</div>
</div>
</div>

<h3>Options Page</h3>
<div class='tile'>
<div>
Expand Down Expand Up @@ -52,7 +71,7 @@ <h3>Timezone</h3>
</div>

<div id='advanced-options' class='hidden'>
<h3>Popup</h3>
<h3>Extension Popup</h3>
<div class='tile'>
<div>
<label class='required' for='display-json-button'>Display 'Copy <code>JSON</code>' button</label>
Expand Down

0 comments on commit 2404a1a

Please sign in to comment.