From bd1fd0a7345dd131619114609ae5b8b4eec9d7a1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 28 Mar 2022 15:17:40 -0600 Subject: [PATCH] Step 13: Update documentation for skinning --- README.md | 7 ---- docs/skinning.md | 79 ++++++++------------------------------------ res/css/_common.scss | 2 +- 3 files changed, 14 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index 9059c5b5b8..1bfc9c5260 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,6 @@ practices that anyone working with the SDK needs to be be aware of and uphold: component is a view or a structure, and then a broad functional grouping (e.g. 'rooms' here) - * After creating a new component you must run `yarn reskindex` to regenerate - the `component-index.js` for the SDK (used in future for skinning) - - * The view's CSS file MUST have the same name (e.g. view/rooms/MessageTile.css). CSS for matrix-react-sdk currently resides in https://github.com/vector-im/element-web/tree/master/src/skins/vector/css/matrix-react-sdk. @@ -158,9 +154,6 @@ cd matrix-react-sdk git checkout develop yarn link matrix-js-sdk yarn install - -# Generate the `component-index.js` file. -yarn reskindex ``` See the [help for `yarn link`](https://classic.yarnpkg.com/docs/cli/link) for diff --git a/docs/skinning.md b/docs/skinning.md index 229bc78372..0186186c24 100644 --- a/docs/skinning.md +++ b/docs/skinning.md @@ -1,71 +1,18 @@ # Skinning -The react-sdk can be skinned to replace presentation components, CSS, or -other relevant parts of the SDK. Typically consumers will replace entire -components and get the ability for custom CSS as a result. +Skinning in the context of the react-sdk is component replacement rather than CSS. This means you can override (replace) +any accessible component in the project to implement custom behaviour, look & feel, etc. Depending on your approach, +overriding CSS classes to apply custom styling is also possible, though harder to do. -This doc isn't exhaustive on how skinning works, though it should cover -some of the more complicated parts such as component replacement. +At present, the react-sdk offers no stable interface for components - this means properties and state can and do change +at any time without notice. Once we determine the react-sdk to be stable enough to use as a proper SDK, we will adjust +this policy. In the meantime, skinning is done completely at your own risk. -## Loading a skin +The approach you take is up to you - we suggest using a module replacement plugin, as found in +[webpack](https://webpack.js.org/plugins/normal-module-replacement-plugin/), though you're free to use whichever build +system works for you. The react-sdk does not have any particular functions to call to load skins, so simply replace or +extend the components/stores/etc you're after and build. As a reminder though, this is done completely at your own risk +as we cannot guarantee a stable interface at this time. -1. Generate a `component-index.js` (preferably using the tools that the react-sdk -exposes). This can typically be done with a npm script like `"reskindex -h src/header"`. -2. In your app's entry point, add something like this code: - ```javascript - import {loadSkin} from "matrix-react-sdk"; - loadSkin(import("component-index").components); - // The rest of your imports go under this. - ``` -3. Import the remainder of the SDK and bootstrap your app. - -It is extremely important that you **do not** import anything else from the -SDK prior to loading your skin as otherwise the skin might not work. Loading -the skin should be one of the first things your app does, if not the very -first thing. - -Additionally, **do not** provide `loadSkin` with the react-sdk components -themselves otherwise the app might explode. The SDK is already aware of its -components and doesn't need to be told. - -## Replacing components - -Components that replace the react-sdk ones MUST have a `replaces` static -key on the component's class to describe which component it overrides. For -example, if your `VectorAuthPage` component is meant to replace the react-sdk -`AuthPage` component then you'd add `static replaces = 'views.auth.AuthPage';` -to the `VectorAuthPage` class. - -Other than that, the skin just needs to be loaded normally as mentioned above. -Consumers of the SDK likely will not be interested in the rest of this section. - -### SDK developer notes - -Components in the react-sdk MUST be decorated with the `@replaceableComponent` -function. For components that can't use the decorator, they must use a -variation that provides similar functionality. The decorator gives consumers -an opportunity to load skinned components by abusing import ordering and -behaviour. - -Decorators are executed at import time which is why we can abuse the import -ordering behaviour: importing `loadSkin` doesn't trigger any components to -be imported, allowing the consumer to specify a skin. When the consumer does -import a component (for example, `MatrixChat`), it starts to pull in all the -components via `import` statements. When the components get pulled in the -decorator checks with the skinned components to see if it should be replacing -the component being imported. The decorator then effectively replaces the -components when needed by specifying the skinned component as an override for -the SDK's component, which should in theory override critical functions like -`render()` and lifecycle event handlers. - -The decorator also means that older usage of `getComponent()` is no longer -required because components should be replaced by the decorator. Eventually -the react-sdk should only have one usage of `getComponent()`: the decorator. - -The decorator assumes that if `getComponent()` returns null that there is -no skinned version of the component and continues on using the SDK's component. -In previous versions of the SDK, the function would throw an error instead -because it also expected the skin to list the SDK's components as well, however -that is no longer possible due to the above. - -In short, components should always be `import`ed. +Taking a look at [element-web](https://github.com/vector-im/element-web)'s approach to skinning may be worthwhile, as it +overrides some relatively simple components. diff --git a/res/css/_common.scss b/res/css/_common.scss index a4b470d052..5372de51df 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -254,7 +254,7 @@ legend { } // These are magic constants which are excluded from tinting, to let themes -// (which only have CSS, unlike skins) tell the app what their non-tinted +// (which only have CSS) tell the app what their non-tinted // colourscheme is by inspecting the stylesheet DOM. // // They are not used for layout!!