Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I want to use styled-components in my app and I am wondering how to organize it.
Basically styled-components are assigned to specific component for reusability.
But what about styled-components which I would like to use many times in other components (for example animations components)?
Should I create a file where I will keep these 'global' styled-components and import it to many components?
Is it good practice?
This is what most of my big production applications built with styled-components look like:
src
├── App
│ ├── Header
│ │ ├── Logo.js
│ │ ├── Title.js
│ │ ├── Subtitle.js
│ │ └── index.js
│ └── Footer
│ ├── List.js
│ ├── ListItem.js
│ ├── Wrapper.js
│ └── index.js
├── shared
│ ├── Button.js
│ ├── Card.js
│ ├── InfiniteList.js
│ ├── EmojiPicker
│ └── Icons
└── index.js
The App folder contains all the specific components that make up your bigger application. (you might structure that by route in your real app) Each of those bigger components is a folder with an index.js file and a bunch of styled components in individual files.
While I'm building my application and I notice I need a styled component from one bigger component in another bigger component, I drag its file to the shared/ folder, update all the imports and that's it! Over time shared/ becomes an improptu pattern library with all of the components I want/need to reuse throughout my entire app.
Another way that's fairly common is to have style.js files in the component folders which contains all of the styled components of that component. The upside being that you have less files that get in your way, but with the downside that it's harder to notice duplication and moving components into the shared folder is more work.
I personally use the first version more often than not, but that's probably just a matter of taste—try them both and see which one you like more!
You can also try Atomic Design to structure your app. This way you will be able to reuse your styled components. Based on Atomic Design methodology, you organize your components into atoms, molecules, organisms, pages and templates.
Atom
An atom is native html tag. For example, an Input element can be an Atom
const Input = props => <input {...props} />
Molecules
Group of atoms is a molecule. For example:
const Field = ({ label, ...inputProps }) => (
<Label>
{label}
<Input {...inputProps} />
</Label>
)
Organisms
Organism is a group of atoms, molecules and/or other organisms. For example:
const Form = (props) => (
<form {...props}>
<Field label="Name" type="text" />
<Field label="Email" type="email" />
</form>
)
Pages
A page is where you will put mostly organisms. For example:
const HomePage = () => (
<PageTemplate header={<Header />}>
<Form />
</PageTemplate>
)
Templates
A template is a layout to be used on pages. For example:
const PageTemplate = ({ header, children }) => (
<main>
{header && <div>{header}</div>}
{children}
</main>
)
Github example
There is a React starter project on Github that uses Atomic Design methodology with styled-components integration. Here is the Link.
The way i am organizing my Project with styled-component is the following:
src
├── Layout
│ ├── Header
│ │ ├── Logo.jsx
│ │ ├── styled.js
│ │ ├── container.js
│ │ └── index.js
│ └── LeftPanel
│ ├── LeftPanel.jsx
│ ├── styled.js
│ └── index.js
└── index.js
Reasoning:
Each folder is a feature.
Each file within a folder have a responsability.
.jsx represent a presentational component.
styled.js are styled components. Manage only how components look. Also any theme related file should be imported here, such as colors,borderStyles, etc.
container.js If we are using any state management we should have an artifact connecting our components with that library. In this case Redux.
index.js exports whatever is relevant.
The advantage that i see with this approach is that is pretty clear where changes have to be made if you decide to use another CSSinJS library.
Hope it make sense for someone else.
Cheers!
Related
I have created a PDF with react-pdf that is downloaded on click on the PDFDownloadLink that is generated within the component that hosts it.
This works fine when I am viewing things on my localhost express server, however once I have deployed this to my test environment, it is having issues with a custom font I have introduced, and I'm not sure as to why it seems like it can't find the font.
I have added the font to /src/fonts/MyFont.woff and have added this to the font-face.css file, but when I am viewing the component on my environment and look in the source tab of dev tools, it doesn't appear that the font is loaded? This is strange, as there is a pre-existing, custom font that I have also had to import manually for the react-pdf stuff, and that seems to work perfectly on the environment... I do know that this is stored elsewhere in another connected repo and have also included my new font in all of the same locations, but it doesn't seem to want to play ball at all.
MyComponent
<PDFDownloadLink
document={<MyPDF />}
fileName="summary.pdf"
>
{({ blob, url, loading, error }) => {
console.log({blob, url, loading, error});
return !!loading ? 'Creating PDF' : 'Download PDF'
}}
</PDFDownloadLink>
MyPDF
import MyFont from '../fonts/MyFont.woff';
const MyPDF = (props) => {
Font.register({
family: 'MyFont',
src: MyFont,
fontStyle: 'normal',
fontWeight: 'normal'
});
// PDF stuff here
font-face.css
#font-face {
font-family: MyFont;
src: url('../fonts/MyFont.woff);
}
The file structure is something along the lines of:
src/
├── css/
│ ├── font-face.css
├── components/
│ ├── MyComponent.jsx
│ └── MyPDF.jsx
└── fonts/
├── MyFont.woff
I have a vue- project with the following src directory tree
├── assets
| └── moderator
| └── css /* css styling for pages and components for moderators, e.g. everything is coloured blue*/
| └── user
| └── css /* css styling for pages and components for users, e.g. everything is coloured orage*/
├── components
| └── moderator /* here are the .vue components for moderators' views */
| └── user /* here are the .vue components for users' views*/
├── main.js
├── router.js
└── vue.config.js
The app will have two types of users :
Moderators
Users
Each type must have its own styling, components for users must use css-styles from assets/user/css, while moderators' from assets/user/css.
If I use scoped import, styling doesn't propagate on external components like those of Bootstrap.
So my questions:
How to set different styling for respective components so that moderator will have everything in blue, and user - in orange?
Is it possible to set style programmatically depending on routes, defined in router?
When you use Style in VueJS the css will render through all components. To use style only in the current component you need to uae scoped. This far you have done right, BUT! Bootstrap and other libraries mostly use components to represent their features so scoped will not work... But there is still a way! You can use >>> before the css you want to work in child-components. >>>b-corousel {color=red;}
I have liked a feature very much in Notepad++, pressing Alt and selecting with the mouse enabled a rectangular selection, just like the selection on desktop...can not think of a proper term for it, maybe rectangular selection or vertical selection or block selection. The cool thing was that it worked also with blank line endings, it generated spaces automatically.
Is there a similar functionality in Atom?
So for example, an use case would be to extract a list of files with tree command :
.
├── element_portals_commands
│ ├── depends.txt
│ └── init.lua
├── element_portals_functional
│ ├── portal_data_api.lua
├── liquid_portals
│ ├── constants.lua
│ ├── crafts.lua
│ ├── depends.txt
│ ├── sounds
│ │ └── fireball_whoosh.ogg
│ └── textures
│ ├── ray_y_tile.png
│ └── README.md
.......
place the multi cursor at a fixed width (the last | for each line represents the cursor)
. |
├── element_portals_commands |
│ ├── depends.txt |
│ └── init.lua |
................
│ ├── sounds |
│ │ └── fireball_whoosh.ogg |
│ └── textures |
│ ├── ray_y_tile.png |
│ └── README.md |
.......
and start typing
. <- |
├── element_portals_commands <- |
│ ├── depends.txt <- |
│ └── init.lua <- |
................
│ ├── sounds <- |
│ │ └── fireball_whoosh.ogg <- |
│ └── textures <- |
│ ├── ray_y_tile.png <- |
│ └── README.md <- |
.......
What I do now to achive this:
Find and replace the end of line \r or \n with a lot of spaces \n
Then Ctrl + Click my way out.
Insert a char.
Trim the end of the line.
I'm sure there is a better way. It is possible without any plugin? Do you know an alternative?
Update :
Some further research showed that
Add selection below alt+shift+↓
places another cursor beneath the current cursor... but it doesn't pad the lines with white spaces. Exists something that also pads the lines ?
First, according to the official site of Notepad++, this function is called column mode editing.
There is a plugin to do similar thing in Atom, but sadly it will just skip lines if that line is not long enough, instaed of filling space. This is the plugin:
Sublime-style-column-select
Today I found a package in Atom named "column-select". So far it works perfectly fine. They way it works is very close to the implementation of Block selection of Rstudio and Kate.
It does not add space to fill the gap. It literally let you select vertically if there is anything there (skips empty lines and lines that does not have enough length).
The following gif from their github shows how it works:
If you want to select a rectangular region in atom all you have to do is first set the horizontal dimension by selecting some text, then set the vertical dimension by holding CTL-SHIFT and then pressing the up or down arrow. Alternatively you can do this the other way around and set the vertical dimension first with CTL-SHIFT, then let go of CTL but keep holding SHIFT and then use the right or left arrow to select the horizontal dimension.
Short version of question
How to apply defined in resource file QSS style to QWidget and QtQuick controls simultaneously?
Full version of question
There is some big project which is written using Qt. For customizing of appearance of controls is used Style Sheet defined in resource file. Now to the project added widget which use QtQuick control. By default control inherited from QWidget looks different with QtQuick controls. So question is: how to extend already existed StyleSheet on QtQuick controls with minimal changes of QtQuick code?
Example
Here is complete example for better describing of my question.
The project has following structure:
.
├── CMakeLists.txt
├── main.cpp
├── MainWidget.cpp
├── MainWidget.h
├── QtWidget.cpp
├── QtWidget.h
├── QuickWidget.cpp
├── QuickWidget.h
└── resources
├── resources.qrc
├── style.qss
└── widget.qml
MainWidget class defines (as expected) the main widget. At the begining MainWidget contains only one widget QtWidget which is inherited from QWidget. For customizing of appearance is used style sheet defined in resources/style.qss. Later QuickWidget class is added to the project. QuickWidget class v QtQuick control which is defined in file: resources/widget.qml. After building and launching application:
mkdir build
cd build
cmake ..
make
./qqcs
the following window will be displayed:
I'm using:
Qt 5.6;
KUbuntu 15.10;
Plasma Desctop.
Is there any way to add a popup (a closable window) with a warning or other message in Shiny - the R package I use to build my web application?
I have been searching for some time but without any results.
Although I don't think there is anything natively available in shiny, you can try adding jQueryUI to your application and using the Dialog widget. See http://jqueryui.com/dialog/.
(Un?)fortunately, you'll be forced to write some JavaScript to make it work.
Per #GSee's suggestion, here's a very minimal example of what it takes to make it work.
You'll need to download jQueryUI and set up a shiny project with a structure like so:
.
├── server.R
├── ui.R
└── www
├── css
│ └── jquery-ui.css
├── images
│ ├── animated-overlay.gif
│ ├── ui-bg_flat_0_aaaaaa_40x100.png
│ ├── ui-bg_flat_75_ffffff_40x100.png
│ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ ├── ui-bg_glass_65_ffffff_1x400.png
│ ├── ui-bg_glass_75_dadada_1x400.png
│ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ ├── ui-bg_glass_95_fef1ec_1x400.png
│ ├── ui-bg_highlight-soft_75_cccccc_1x100.png
│ ├── ui-icons_222222_256x240.png
│ ├── ui-icons_2e83ff_256x240.png
│ ├── ui-icons_454545_256x240.png
│ ├── ui-icons_888888_256x240.png
│ └── ui-icons_cd0a0a_256x240.png
└── js
└── jquery-ui.js
(all of the image icons come part of jQueryUI)
Next, add a file called scripts.js (or whatever you like) to the www/js folder, containing the following
$( function() {
$("#dialog").dialog();
})
This calls the jQueryUI dialog initializer on the element with id dialog.
Next, have a server.R and ui.R as follows:
server.R
--------
library(shiny)
shinyServer( function(input, output, session) {
## a very unsafe, basic access to the R console
output$dialog <- renderPrint({
code <- input$console
output <- eval( parse( text=code ) )
return(output)
})
})
and
ui.R
----
library(shiny)
shinyUI(bootstrapPage(
includeCSS("www/css/jquery-ui.css"),
includeScript("www/js/jquery-ui.js"),
includeScript("www/js/scripts.js"),
textInput("console", "Enter an R Command"),
uiOutput("dialog")
))
Now, if you do runApp(), you should see the results of evaluation of any code you write into the text input console appearing in the dialog box.
Now, the question is, how can we minimize it, or only show it when, say, error code is produced? That I'll have to leave for you, because I think it'll be tricky. Some options:
Figure out how to get our R code to send, or trigger, some JavaScript to show or hide the element. An example (not mine) using this to temporarily disable a button is here.
Attach a (JavaScript) observer or trigger to the output produced, and if you see an error (or output otherwise conforming in some way), show the box; otherwise hide it.
Generate an actual Shiny input/output pair to handle behavior as desired. (Brief tutorial at http://rstudio.github.io/shiny/tutorial/#building-inputs)
If you want to get a bit more out of your jQueryUI dialog, you can also try the extension jQuery-dialogextend here.
And, disclaimer: the console here is only for demonstrative purposes; please don't put any shiny apps that run unsanitized code from the user into the wild!
There is this new R package out there - shinyBS which brings many twitter bootstrap functionality into shiny like alerts, tooltips, popovers, modal dialogs, progress bars etc...
shinyBS
Bolaka is right, install and load the shinyBS package, then run bsExample("Alerts") to see an example with code you can copy and paste.